|
@@ -175,6 +175,7 @@ struct bond_parm_tbl bond_mode_tbl[] = {
|
|
|
struct bond_parm_tbl xmit_hashtype_tbl[] = {
|
|
|
{ "layer2", BOND_XMIT_POLICY_LAYER2},
|
|
|
{ "layer3+4", BOND_XMIT_POLICY_LAYER34},
|
|
|
+{ "layer2+3", BOND_XMIT_POLICY_LAYER23},
|
|
|
{ NULL, -1},
|
|
|
};
|
|
|
|
|
@@ -3604,6 +3605,24 @@ void bond_unregister_arp(struct bonding *bond)
|
|
|
|
|
|
/*---------------------------- 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
|
|
|
* the packet is a frag or not TCP or UDP, just use layer 3 data. If it is
|
|
@@ -4306,6 +4325,22 @@ out:
|
|
|
|
|
|
/*------------------------- 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
|
|
|
*/
|
|
@@ -4322,10 +4357,7 @@ void bond_set_mode_ops(struct bonding *bond, int mode)
|
|
|
break;
|
|
|
case BOND_MODE_XOR:
|
|
|
bond_dev->hard_start_xmit = bond_xmit_xor;
|
|
|
- if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34)
|
|
|
- bond->xmit_hash_policy = bond_xmit_hash_policy_l34;
|
|
|
- else
|
|
|
- bond->xmit_hash_policy = bond_xmit_hash_policy_l2;
|
|
|
+ bond_set_xmit_hash_policy(bond);
|
|
|
break;
|
|
|
case BOND_MODE_BROADCAST:
|
|
|
bond_dev->hard_start_xmit = bond_xmit_broadcast;
|
|
@@ -4333,10 +4365,7 @@ void bond_set_mode_ops(struct bonding *bond, int mode)
|
|
|
case BOND_MODE_8023AD:
|
|
|
bond_set_master_3ad_flags(bond);
|
|
|
bond_dev->hard_start_xmit = bond_3ad_xmit_xor;
|
|
|
- if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34)
|
|
|
- bond->xmit_hash_policy = bond_xmit_hash_policy_l34;
|
|
|
- else
|
|
|
- bond->xmit_hash_policy = bond_xmit_hash_policy_l2;
|
|
|
+ bond_set_xmit_hash_policy(bond);
|
|
|
break;
|
|
|
case BOND_MODE_ALB:
|
|
|
bond_set_master_alb_flags(bond);
|
|
@@ -4498,8 +4527,7 @@ int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl)
|
|
|
for (i = 0; tbl[i].modename; i++) {
|
|
|
if ((isdigit(*mode_arg) &&
|
|
|
tbl[i].mode == simple_strtol(mode_arg, NULL, 0)) ||
|
|
|
- (strncmp(mode_arg, tbl[i].modename,
|
|
|
- strlen(tbl[i].modename)) == 0)) {
|
|
|
+ (strcmp(mode_arg, tbl[i].modename) == 0)) {
|
|
|
return tbl[i].mode;
|
|
|
}
|
|
|
}
|