On 2/21/18 9:22 AM, Ido Schimmel wrote:

>> +u32 rt6_multipath_hash(const struct net *net, const struct flowi6 *fl6,
>> +                   const struct sk_buff *skb)
>>  {
>>      struct flow_keys hash_keys;
>>      u32 mhash;
>>  
>> -    memset(&hash_keys, 0, sizeof(hash_keys));
>> -    hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
>> -    if (skb) {
>> -            ip6_multipath_l3_keys(skb, &hash_keys);
>> -    } else {
>> -            hash_keys.addrs.v6addrs.src = fl6->saddr;
>> -            hash_keys.addrs.v6addrs.dst = fl6->daddr;
>> -            hash_keys.tags.flow_label = (__force u32)fl6->flowlabel;
>> -            hash_keys.basic.ip_proto = fl6->flowi6_proto;
>> +    switch (net->ipv6.sysctl.multipath_hash_policy) {
>> +    case 0:
>> +            memset(&hash_keys, 0, sizeof(hash_keys));
>> +            hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
>> +            if (skb) {
>> +                    ip6_multipath_l3_keys(skb, &hash_keys);
>> +            } else {
>> +                    hash_keys.addrs.v6addrs.src = fl6->saddr;
>> +                    hash_keys.addrs.v6addrs.dst = fl6->daddr;
>> +                    hash_keys.tags.flow_label = (__force u32)fl6->flowlabel;
>> +                    hash_keys.basic.ip_proto = fl6->flowi6_proto;
>> +            }
>> +            break;
>> +    case 1:
>> +            if (skb) {
>> +                    unsigned int flag = FLOW_DISSECTOR_F_STOP_AT_ENCAP;
>> +                    struct flow_keys keys;
>> +
>> +                    /* short-circuit if we already have L4 hash present */
>> +                    if (skb->l4_hash)
>> +                            return skb_get_hash_raw(skb) >> 1;
>> +
>> +                    memset(&hash_keys, 0, sizeof(hash_keys));
>> +
>> +                    skb_flow_dissect_flow_keys(skb, &keys, flag);
>> +
>> +                    hash_keys.addrs.v6addrs.src = keys.addrs.v6addrs.src;
>> +                    hash_keys.addrs.v6addrs.dst = keys.addrs.v6addrs.dst;
> 
> Shouldn't you add:
> 
> hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
> 
> ?
> 
> Otherwise flow_hash_from_keys() will not consistentify the ports and the
> addresses and it will also not use the addresses for the hash
> computation.
> 
> It's missing from fib_multipath_hash() as well, so I might be missing
> something.

Yes, I think you are correct. The oversight here is based on the missing
set in the ipv4 variant.

> 
>> +                    hash_keys.ports.src = keys.ports.src;
>> +                    hash_keys.ports.dst = keys.ports.dst;
>> +                    hash_keys.tags.flow_label = keys.tags.flow_label;
> 
> Why are you using the flow label?

will remove. It is supposed to be an L4 hash.

Reply via email to