* [RFC 1/4] bond: cleanup transmit hash policy interface
2010-02-04 17:11 [RFC 0/4] bond hashing revised Stephen Hemminger
@ 2010-02-04 17:11 ` Stephen Hemminger
2010-02-04 17:11 ` [RFC 2/4] bond: add IPV6 layer3 hash policy support Stephen Hemminger
` (3 subsequent siblings)
4 siblings, 0 replies; 10+ messages in thread
From: Stephen Hemminger @ 2010-02-04 17:11 UTC (permalink / raw)
To: David Miller, Jay Vosburgh; +Cc: netdev, bonding-devel
[-- Attachment #1: bond-hash1.patch --]
[-- Type: text/plain, Size: 4288 bytes --]
Some minor cleanups of hash policy with no change in resulting
interface.
1. Do modulus operation in caller rather than policy
2. Pass skb as constant pointer
3. Use common code for layer 2 policy hash
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/drivers/net/bonding/bond_3ad.c 2010-02-04 08:56:36.106130909 -0800
+++ b/drivers/net/bonding/bond_3ad.c 2010-02-04 08:57:46.736130667 -0800
@@ -2413,7 +2413,7 @@ int bond_3ad_xmit_xor(struct sk_buff *sk
goto out;
}
- slave_agg_no = bond->xmit_hash_policy(skb, slaves_in_agg);
+ slave_agg_no = bond->xmit_hash_policy(skb) % slaves_in_agg;
bond_for_each_slave(bond, slave, i) {
struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator;
--- a/drivers/net/bonding/bond_main.c 2010-02-04 08:56:56.015821641 -0800
+++ b/drivers/net/bonding/bond_main.c 2010-02-04 08:57:46.736130667 -0800
@@ -3584,20 +3584,30 @@ void bond_unregister_arp(struct bonding
/*---------------------------- Hashing Policies -----------------------------*/
/*
+ * Hash for the output device based upon layer 2 data
+ */
+static u16 bond_xmit_hash_policy_l2(const struct sk_buff *skb)
+{
+ const struct ethhdr *data = eth_hdr(skb);
+
+ return data->h_dest[5] ^ data->h_source[5];
+}
+
+/*
* 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, int count)
+static u16 bond_xmit_hash_policy_l23(const struct sk_buff *skb)
{
- struct ethhdr *data = (struct ethhdr *)skb->data;
- struct iphdr *iph = ip_hdr(skb);
+ const struct ethhdr *data = eth_hdr(skb);
if (skb->protocol == htons(ETH_P_IP)) {
- return ((ntohl(iph->saddr ^ iph->daddr) & 0xffff) ^
- (data->h_dest[5] ^ data->h_source[5])) % count;
+ const struct iphdr *iph = ip_hdr(skb);
+ return ntohl(iph->saddr ^ iph->daddr) ^
+ (data->h_dest[5] ^ data->h_source[5]);
}
- return (data->h_dest[5] ^ data->h_source[5]) % count;
+ return bond_xmit_hash_policy_l2(skb);
}
/*
@@ -3605,36 +3615,28 @@ static int bond_xmit_hash_policy_l23(str
* the packet is a frag or not TCP or UDP, just use layer 3 data. If it is
* altogether not IP, mimic bond_xmit_hash_policy_l2()
*/
-static int bond_xmit_hash_policy_l34(struct sk_buff *skb, int count)
+static u16 bond_xmit_hash_policy_l34(const struct sk_buff *skb)
{
- struct ethhdr *data = (struct ethhdr *)skb->data;
- struct iphdr *iph = ip_hdr(skb);
- __be16 *layer4hdr = (__be16 *)((u32 *)iph + iph->ihl);
- int layer4_xor = 0;
+ const struct ethhdr *data = eth_hdr(skb);
if (skb->protocol == htons(ETH_P_IP)) {
+ const struct iphdr *iph = ip_hdr(skb);
+ const __be16 *layer4hdr
+ = ((const void *)iph + iph->ihl);
+ u32 layer4_xor = 0;
+
if (!(iph->frag_off & htons(IP_MF|IP_OFFSET)) &&
(iph->protocol == IPPROTO_TCP ||
iph->protocol == IPPROTO_UDP)) {
layer4_xor = ntohs((*layer4hdr ^ *(layer4hdr + 1)));
}
- return (layer4_xor ^
- ((ntohl(iph->saddr ^ iph->daddr)) & 0xffff)) % count;
+ return layer4_xor ^ ntohl(iph->saddr ^ iph->daddr);
}
- return (data->h_dest[5] ^ data->h_source[5]) % count;
+ return bond_xmit_hash_policy_l2(skb);
}
-/*
- * Hash for the output device based upon layer 2 data
- */
-static int bond_xmit_hash_policy_l2(struct sk_buff *skb, int count)
-{
- struct ethhdr *data = (struct ethhdr *)skb->data;
-
- return (data->h_dest[5] ^ data->h_source[5]) % count;
-}
/*-------------------------- Device entry points ----------------------------*/
@@ -4224,7 +4226,7 @@ static int bond_xmit_xor(struct sk_buff
if (!BOND_IS_OK(bond))
goto out;
- slave_no = bond->xmit_hash_policy(skb, bond->slave_cnt);
+ slave_no = bond->xmit_hash_policy(skb) % bond->slave_cnt;
bond_for_each_slave(bond, slave, i) {
slave_no--;
--- a/drivers/net/bonding/bonding.h 2010-02-04 08:56:56.015821641 -0800
+++ b/drivers/net/bonding/bonding.h 2010-02-04 08:57:46.736130667 -0800
@@ -203,7 +203,7 @@ struct bonding {
#endif /* CONFIG_PROC_FS */
struct list_head bond_list;
struct dev_mc_list *mc_list;
- int (*xmit_hash_policy)(struct sk_buff *, int);
+ u16 (*xmit_hash_policy)(const struct sk_buff *);
__be32 master_ip;
u16 flags;
u16 rr_tx_counter;
--
^ permalink raw reply [flat|nested] 10+ messages in thread
* [RFC 2/4] bond: add IPV6 layer3 hash policy support
2010-02-04 17:11 [RFC 0/4] bond hashing revised Stephen Hemminger
2010-02-04 17:11 ` [RFC 1/4] bond: cleanup transmit hash policy interface Stephen Hemminger
@ 2010-02-04 17:11 ` Stephen Hemminger
2010-02-04 17:11 ` [RFC 3/4] bond: support more Layer 4 protocols Stephen Hemminger
` (2 subsequent siblings)
4 siblings, 0 replies; 10+ messages in thread
From: Stephen Hemminger @ 2010-02-04 17:11 UTC (permalink / raw)
To: David Miller, Jay Vosburgh; +Cc: netdev, bonding-devel
[-- Attachment #1: bond-ipv6.patch --]
[-- Type: text/plain, Size: 2176 bytes --]
Add IPV6 support to Layer 3 and Layer 3+4 hash policies.
Code take fron SFQ.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/drivers/net/bonding/bond_main.c 2010-02-04 08:58:54.617692952 -0800
+++ b/drivers/net/bonding/bond_main.c 2010-02-04 09:08:00.447069200 -0800
@@ -3601,13 +3601,24 @@ static u16 bond_xmit_hash_policy_l23(con
{
const struct ethhdr *data = eth_hdr(skb);
- if (skb->protocol == htons(ETH_P_IP)) {
+ switch (skb->protocol) {
+ case htons(ETH_P_IP):
+ {
const struct iphdr *iph = ip_hdr(skb);
return ntohl(iph->saddr ^ iph->daddr) ^
(data->h_dest[5] ^ data->h_source[5]);
}
+ case htons(ETH_P_IPV6):
+ {
+ const struct ipv6hdr *iph = ipv6_hdr(skb);
+ return ntohl(iph->saddr.s6_addr32[3] ^
+ iph->daddr.s6_addr32[3]) ^
+ (data->h_dest[5] ^ data->h_source[5]);
- return bond_xmit_hash_policy_l2(skb);
+ }
+ default:
+ return bond_xmit_hash_policy_l2(skb);
+ }
}
/*
@@ -3617,9 +3628,9 @@ static u16 bond_xmit_hash_policy_l23(con
*/
static u16 bond_xmit_hash_policy_l34(const struct sk_buff *skb)
{
- const struct ethhdr *data = eth_hdr(skb);
-
- if (skb->protocol == htons(ETH_P_IP)) {
+ switch (skb->protocol) {
+ case htons(ETH_P_IP):
+ {
const struct iphdr *iph = ip_hdr(skb);
const __be16 *layer4hdr
= ((const void *)iph + iph->ihl);
@@ -3627,14 +3638,28 @@ static u16 bond_xmit_hash_policy_l34(con
if (!(iph->frag_off & htons(IP_MF|IP_OFFSET)) &&
(iph->protocol == IPPROTO_TCP ||
- iph->protocol == IPPROTO_UDP)) {
+ iph->protocol == IPPROTO_UDP))
layer4_xor = ntohs((*layer4hdr ^ *(layer4hdr + 1)));
- }
+
return layer4_xor ^ ntohl(iph->saddr ^ iph->daddr);
+ }
+ case htons(ETH_P_IPV6):
+ {
+ const struct ipv6hdr *iph = ipv6_hdr(skb);
+ const __be16 *layer4hdr = (const __be16 *) (iph + 1);
+ u32 layer4_xor = 0;
+ if (iph->nexthdr == IPPROTO_TCP ||
+ iph->nexthdr == IPPROTO_UDP)
+ layer4_xor = ntohs((*layer4hdr ^ *(layer4hdr + 1)));
+
+ return layer4_xor ^
+ ntohl(iph->saddr.s6_addr32[3] ^ iph->daddr.s6_addr32[3]);
+ }
+ default:
+ return bond_xmit_hash_policy_l2(skb);
}
- return bond_xmit_hash_policy_l2(skb);
}
--
^ permalink raw reply [flat|nested] 10+ messages in thread
* [RFC 3/4] bond: support more Layer 4 protocols
2010-02-04 17:11 [RFC 0/4] bond hashing revised Stephen Hemminger
2010-02-04 17:11 ` [RFC 1/4] bond: cleanup transmit hash policy interface Stephen Hemminger
2010-02-04 17:11 ` [RFC 2/4] bond: add IPV6 layer3 hash policy support Stephen Hemminger
@ 2010-02-04 17:11 ` Stephen Hemminger
2010-02-05 10:38 ` Patrick McHardy
2010-02-04 17:11 ` [RFC 4/4] bond: add new multiqueue hash policy Stephen Hemminger
2010-02-05 9:40 ` [RFC 0/4] bond hashing revised Jasper Spaans
4 siblings, 1 reply; 10+ messages in thread
From: Stephen Hemminger @ 2010-02-04 17:11 UTC (permalink / raw)
To: David Miller, Jay Vosburgh; +Cc: netdev, bonding-devel
[-- Attachment #1: bond-more-proto.patch --]
[-- Type: text/plain, Size: 1752 bytes --]
There are several protocols similar to TCP and UDP which share common L4
header format. Since proto is only one byte, use a map rather than big
conditonal.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/drivers/net/bonding/bond_main.c 2010-02-04 09:08:00.447069200 -0800
+++ b/drivers/net/bonding/bond_main.c 2010-02-04 09:08:42.545818691 -0800
@@ -3621,6 +3621,16 @@ static u16 bond_xmit_hash_policy_l23(con
}
}
+/* Map of protocols with standard ports available to include in hash */
+static const bool has_layer4[256] = {
+ [IPPROTO_TCP] = 1,
+ [IPPROTO_UDP] = 1,
+ [IPPROTO_UDPLITE] = 1,
+ [IPPROTO_SCTP] = 1,
+ [IPPROTO_DCCP] = 1,
+ [IPPROTO_ESP] = 1,
+};
+
/*
* 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
@@ -3634,11 +3644,10 @@ static u16 bond_xmit_hash_policy_l34(con
const struct iphdr *iph = ip_hdr(skb);
const __be16 *layer4hdr
= ((const void *)iph + iph->ihl);
- u32 layer4_xor = 0;
+ u16 layer4_xor = 0;
if (!(iph->frag_off & htons(IP_MF|IP_OFFSET)) &&
- (iph->protocol == IPPROTO_TCP ||
- iph->protocol == IPPROTO_UDP))
+ has_layer4[iph->protocol])
layer4_xor = ntohs((*layer4hdr ^ *(layer4hdr + 1)));
return layer4_xor ^ ntohl(iph->saddr ^ iph->daddr);
@@ -3647,10 +3656,9 @@ static u16 bond_xmit_hash_policy_l34(con
{
const struct ipv6hdr *iph = ipv6_hdr(skb);
const __be16 *layer4hdr = (const __be16 *) (iph + 1);
- u32 layer4_xor = 0;
+ u16 layer4_xor = 0;
- if (iph->nexthdr == IPPROTO_TCP ||
- iph->nexthdr == IPPROTO_UDP)
+ if (has_layer4[iph->nexthdr])
layer4_xor = ntohs((*layer4hdr ^ *(layer4hdr + 1)));
return layer4_xor ^
--
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC 3/4] bond: support more Layer 4 protocols
2010-02-04 17:11 ` [RFC 3/4] bond: support more Layer 4 protocols Stephen Hemminger
@ 2010-02-05 10:38 ` Patrick McHardy
2010-02-05 16:42 ` Stephen Hemminger
0 siblings, 1 reply; 10+ messages in thread
From: Patrick McHardy @ 2010-02-05 10:38 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: David Miller, Jay Vosburgh, netdev, bonding-devel
Stephen Hemminger wrote:
> +/* Map of protocols with standard ports available to include in hash */
> +static const bool has_layer4[256] = {
> + [IPPROTO_TCP] = 1,
> + [IPPROTO_UDP] = 1,
> + [IPPROTO_UDPLITE] = 1,
> + [IPPROTO_SCTP] = 1,
> + [IPPROTO_DCCP] = 1,
> + [IPPROTO_ESP] = 1,
> +};
> +
How about using a bitmap or u8s to keep this more compact?
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC 3/4] bond: support more Layer 4 protocols
2010-02-05 10:38 ` Patrick McHardy
@ 2010-02-05 16:42 ` Stephen Hemminger
2010-02-08 13:11 ` Patrick McHardy
0 siblings, 1 reply; 10+ messages in thread
From: Stephen Hemminger @ 2010-02-05 16:42 UTC (permalink / raw)
To: Patrick McHardy; +Cc: David Miller, Jay Vosburgh, netdev, bonding-devel
On Fri, 05 Feb 2010 11:38:05 +0100
Patrick McHardy <kaber@trash.net> wrote:
> Stephen Hemminger wrote:
> > +/* Map of protocols with standard ports available to include in hash */
> > +static const bool has_layer4[256] = {
> > + [IPPROTO_TCP] = 1,
> > + [IPPROTO_UDP] = 1,
> > + [IPPROTO_UDPLITE] = 1,
> > + [IPPROTO_SCTP] = 1,
> > + [IPPROTO_DCCP] = 1,
> > + [IPPROTO_ESP] = 1,
> > +};
> > +
>
> How about using a bitmap or u8s to keep this more compact?
I thought about that, but couldn't find a clever way to initialize at
compile time other than hardcoding constants?
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC 3/4] bond: support more Layer 4 protocols
2010-02-05 16:42 ` Stephen Hemminger
@ 2010-02-08 13:11 ` Patrick McHardy
0 siblings, 0 replies; 10+ messages in thread
From: Patrick McHardy @ 2010-02-08 13:11 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: David Miller, Jay Vosburgh, netdev, bonding-devel
Stephen Hemminger wrote:
> On Fri, 05 Feb 2010 11:38:05 +0100
> Patrick McHardy <kaber@trash.net> wrote:
>
>> Stephen Hemminger wrote:
>>> +/* Map of protocols with standard ports available to include in hash */
>>> +static const bool has_layer4[256] = {
>>> + [IPPROTO_TCP] = 1,
>>> + [IPPROTO_UDP] = 1,
>>> + [IPPROTO_UDPLITE] = 1,
>>> + [IPPROTO_SCTP] = 1,
>>> + [IPPROTO_DCCP] = 1,
>>> + [IPPROTO_ESP] = 1,
>>> +};
>>> +
>> How about using a bitmap or u8s to keep this more compact?
>
> I thought about that, but couldn't find a clever way to initialize at
> compile time other than hardcoding constants?
Maybe an __init function with a couple of set_bit() calls?
Otherwise I'd suggest to simply use u8.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [RFC 4/4] bond: add new multiqueue hash policy
2010-02-04 17:11 [RFC 0/4] bond hashing revised Stephen Hemminger
` (2 preceding siblings ...)
2010-02-04 17:11 ` [RFC 3/4] bond: support more Layer 4 protocols Stephen Hemminger
@ 2010-02-04 17:11 ` Stephen Hemminger
2010-02-05 9:40 ` [RFC 0/4] bond hashing revised Jasper Spaans
4 siblings, 0 replies; 10+ messages in thread
From: Stephen Hemminger @ 2010-02-04 17:11 UTC (permalink / raw)
To: David Miller, Jay Vosburgh; +Cc: netdev, bonding-devel
[-- Attachment #1: bond-jhash.patch --]
[-- Type: text/plain, Size: 1686 bytes --]
This hash policy just uses existing transmit hash used for
mulitiqueue.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/drivers/net/bonding/bond_main.c 2010-02-04 08:57:52.356755294 -0800
+++ b/drivers/net/bonding/bond_main.c 2010-02-04 08:57:53.036755256 -0800
@@ -190,6 +190,7 @@ const struct bond_parm_tbl xmit_hashtype
{ "layer2", BOND_XMIT_POLICY_LAYER2},
{ "layer3+4", BOND_XMIT_POLICY_LAYER34},
{ "layer2+3", BOND_XMIT_POLICY_LAYER23},
+{ "multiqueue", BOND_XMIT_POLICY_MQ},
{ NULL, -1},
};
@@ -3670,6 +3671,13 @@ static u16 bond_xmit_hash_policy_l34(con
}
+/*
+ * Hash for the output device based on multiqueue transmit hash policy
+ */
+static u16 bond_xmit_hash_policy_mq(const struct sk_buff *skb)
+{
+ return skb_tx_hash(skb->dev, skb);
+}
/*-------------------------- Device entry points ----------------------------*/
@@ -4350,6 +4358,9 @@ out:
static void bond_set_xmit_hash_policy(struct bonding *bond)
{
switch (bond->params.xmit_policy) {
+ case BOND_XMIT_POLICY_MQ:
+ bond->xmit_hash_policy = bond_xmit_hash_policy_mq;
+ break;
case BOND_XMIT_POLICY_LAYER23:
bond->xmit_hash_policy = bond_xmit_hash_policy_l23;
break;
--- a/include/linux/if_bonding.h 2010-02-04 08:56:35.956131096 -0800
+++ b/include/linux/if_bonding.h 2010-02-04 08:57:53.036755256 -0800
@@ -87,6 +87,7 @@
#define BOND_XMIT_POLICY_LAYER2 0 /* layer 2 (MAC only), default */
#define BOND_XMIT_POLICY_LAYER34 1 /* layer 3+4 (IP ^ (TCP || UDP)) */
#define BOND_XMIT_POLICY_LAYER23 2 /* layer 2+3 (IP ^ MAC) */
+#define BOND_XMIT_POLICY_MQ 3 /* transmit hash (multiqueue) */
typedef struct ifbond {
__s32 bond_mode;
--
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC 0/4] bond hashing revised
2010-02-04 17:11 [RFC 0/4] bond hashing revised Stephen Hemminger
` (3 preceding siblings ...)
2010-02-04 17:11 ` [RFC 4/4] bond: add new multiqueue hash policy Stephen Hemminger
@ 2010-02-05 9:40 ` Jasper Spaans
2010-02-05 21:04 ` Stephen Hemminger
4 siblings, 1 reply; 10+ messages in thread
From: Jasper Spaans @ 2010-02-05 9:40 UTC (permalink / raw)
To: Stephen Hemminger
Cc: David Miller, Jay Vosburgh, netdev@vger.kernel.org,
bonding-devel@lists.sourceforge.net
On 04/02/10 17:11, Stephen Hemminger wrote:
> These have not been tested yet. I need to try them with some
> different flows/hardware to validate.
>
Glancing over these patches, all four of them look fine to me.
The only thing missing is some documentation in
Documentation/networking/bonding.txt (I have no idea what multiqueue is
supposed to do, but if you tell me I'll volunteer).
Cheers,
Jasper
--
Ir. Jasper Spaans
Fox-IT Experts in IT Security!
T: +31 (0) 15 284 79 99
KvK Haaglanden 27301624
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC 0/4] bond hashing revised
2010-02-05 9:40 ` [RFC 0/4] bond hashing revised Jasper Spaans
@ 2010-02-05 21:04 ` Stephen Hemminger
0 siblings, 0 replies; 10+ messages in thread
From: Stephen Hemminger @ 2010-02-05 21:04 UTC (permalink / raw)
To: Jasper Spaans
Cc: David Miller, Jay Vosburgh, netdev@vger.kernel.org,
bonding-devel@lists.sourceforge.net
On Fri, 5 Feb 2010 09:40:17 +0000
Jasper Spaans <spaans@fox-it.com> wrote:
> On 04/02/10 17:11, Stephen Hemminger wrote:
> > These have not been tested yet. I need to try them with some
> > different flows/hardware to validate.
> >
> Glancing over these patches, all four of them look fine to me.
>
> The only thing missing is some documentation in
> Documentation/networking/bonding.txt (I have no idea what multiqueue is
> supposed to do, but if you tell me I'll volunteer).
>
Did you look at kernel Documentation/networking/multiqueue.txt?
^ permalink raw reply [flat|nested] 10+ messages in thread