Split bonding hashes patch.
[linux-2.6.git] / linux-2.6-721-bonding-layer3.patch
diff --git a/linux-2.6-721-bonding-layer3.patch b/linux-2.6-721-bonding-layer3.patch
new file mode 100644 (file)
index 0000000..521b318
--- /dev/null
@@ -0,0 +1,64 @@
+diff -Nurp linux-2.6.22.19-vs2.3.0.34.bond1/drivers/net/bonding/bond_main.c linux-2.6.22.19-vs2.3.0.34.bond2/drivers/net/bonding/bond_main.c
+--- linux-2.6.22.19-vs2.3.0.34.bond1/drivers/net/bonding/bond_main.c   2009-06-23 00:51:24.000000000 +0200
++++ linux-2.6.22.19-vs2.3.0.34.bond2/drivers/net/bonding/bond_main.c   2009-06-23 01:02:56.000000000 +0200
+@@ -171,6 +171,7 @@ struct bond_parm_tbl xmit_hashtype_tbl[]
+ {     "layer2",               BOND_XMIT_POLICY_LAYER2},
+ {     "layer3+4",             BOND_XMIT_POLICY_LAYER34},
+ {     "layer2+3",             BOND_XMIT_POLICY_LAYER23},
++{     "layer3",               BOND_XMIT_POLICY_LAYER3},
+ {     NULL,                   -1},
+ };
+@@ -3450,6 +3451,22 @@ void bond_unregister_arp(struct bonding 
+ /*---------------------------- Hashing Policies -----------------------------*/
+  
+ /*
++ * Hash for the output device based upon layer 3 data. If the packet
++ * is not IP mimic bond_xmit_hash_policy_l2()
++ */
++static int bond_xmit_hash_policy_l3(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) % count;
++      else
++              return (data->h_dest[5] ^ bond_dev->dev_addr[5]) % count;
++}
++
++/*
+  * 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()
+  */
+@@ -4204,7 +4221,9 @@ void bond_set_mode_ops(struct bonding *b
+                       bond->xmit_hash_policy = bond_xmit_hash_policy_l34;
+               else if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER23)
+                       bond->xmit_hash_policy = bond_xmit_hash_policy_l23;
++              else if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER3)
++                      bond->xmit_hash_policy = bond_xmit_hash_policy_l3;
+               else
+                       bond->xmit_hash_policy = bond_xmit_hash_policy_l2;
+               break;
+@@ -4217,7 +4236,9 @@ void bond_set_mode_ops(struct bonding *b
+               if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34)
+                       bond->xmit_hash_policy = bond_xmit_hash_policy_l34;
+               else if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER23)
+                       bond->xmit_hash_policy = bond_xmit_hash_policy_l23;
++              else if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER3)
++                      bond->xmit_hash_policy = bond_xmit_hash_policy_l3;
+               else
+                       bond->xmit_hash_policy = bond_xmit_hash_policy_l2;
+               break;
+diff -Nurp linux-2.6.22.19-vs2.3.0.34.bond1/include/linux/if_bonding.h linux-2.6.22.19-vs2.3.0.34.bond2/include/linux/if_bonding.h
+--- linux-2.6.22.19-vs2.3.0.34.bond1/include/linux/if_bonding.h        2009-06-23 00:49:47.000000000 +0200
++++ linux-2.6.22.19-vs2.3.0.34.bond2/include/linux/if_bonding.h        2009-06-23 01:02:07.000000000 +0200
+@@ -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 ^ MAC) */
+ #define BOND_XMIT_POLICY_LAYER23      2 /* layer 2+3 (IP ^ MAC) */
++#define BOND_XMIT_POLICY_LAYER3               3 /* layer3 (IP only) */
+ typedef struct ifbond {
+       __s32 bond_mode;