Merge https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
[sfrench/cifs-2.6.git] / drivers / net / bonding / bond_main.c
index 15eddca7b4b6623ccb2b17d1d8f9a092ebd90ff5..38e152548126101b1c7a8f85014c55fed4d88de0 100644 (file)
@@ -4027,14 +4027,19 @@ static bool bond_flow_dissect(struct bonding *bond, struct sk_buff *skb, const v
        return true;
 }
 
-static u32 bond_ip_hash(u32 hash, struct flow_keys *flow)
+static u32 bond_ip_hash(u32 hash, struct flow_keys *flow, int xmit_policy)
 {
        hash ^= (__force u32)flow_get_u32_dst(flow) ^
                (__force u32)flow_get_u32_src(flow);
        hash ^= (hash >> 16);
        hash ^= (hash >> 8);
+
        /* discard lowest hash bit to deal with the common even ports pattern */
-       return hash >> 1;
+       if (xmit_policy == BOND_XMIT_POLICY_LAYER34 ||
+               xmit_policy == BOND_XMIT_POLICY_ENCAP34)
+               return hash >> 1;
+
+       return hash;
 }
 
 /* Generate hash based on xmit policy. If @skb is given it is used to linearize
@@ -4064,7 +4069,7 @@ static u32 __bond_xmit_hash(struct bonding *bond, struct sk_buff *skb, const voi
                        memcpy(&hash, &flow.ports.ports, sizeof(hash));
        }
 
-       return bond_ip_hash(hash, &flow);
+       return bond_ip_hash(hash, &flow, bond->params.xmit_policy);
 }
 
 /**
@@ -5259,7 +5264,7 @@ static u32 bond_sk_hash_l34(struct sock *sk)
        /* L4 */
        memcpy(&hash, &flow.ports.ports, sizeof(hash));
        /* L3 */
-       return bond_ip_hash(hash, &flow);
+       return bond_ip_hash(hash, &flow, BOND_XMIT_POLICY_LAYER34);
 }
 
 static struct net_device *__bond_sk_get_lower_dev(struct bonding *bond,