On 13/06/2019 20:03, Stephen Suryaputra wrote: > Multipath hash policy value of 0 isn't distributing since the outer IP > dest and src aren't varied eventhough the inner ones are. Since the flow > is on the inner ones in the case of tunneled traffic, hashing on them is > desired. > > This is done mainly for IP over GRE, hence only tested for that. But > anything else supported by flow dissection should work. > > v2: Use skb_flow_dissect_flow_keys() directly so that other tunneling > can be supported through flow dissection (per Nikolay Aleksandrov). > Signed-off-by: Stephen Suryaputra <ssuryae...@gmail.com> > --- > Documentation/networking/ip-sysctl.txt | 1 + > net/ipv4/route.c | 20 ++++++++++++++++++++ > net/ipv4/sysctl_net_ipv4.c | 2 +- > 3 files changed, 22 insertions(+), 1 deletion(-) > > diff --git a/Documentation/networking/ip-sysctl.txt > b/Documentation/networking/ip-sysctl.txt > index 5eedc6941ce5..2f3bc910895a 100644 > --- a/Documentation/networking/ip-sysctl.txt > +++ b/Documentation/networking/ip-sysctl.txt > @@ -80,6 +80,7 @@ fib_multipath_hash_policy - INTEGER > Possible values: > 0 - Layer 3 > 1 - Layer 4 > + 2 - Inner Layer 3 for tunneled IP packets.
Hmm, but you're using the ports below, so it's not L3 ? > > fib_sync_mem - UNSIGNED INTEGER > Amount of dirty memory from fib entries that can be backlogged before > diff --git a/net/ipv4/route.c b/net/ipv4/route.c > index 14c7fdacaa72..c3e03bce0a3a 100644 > --- a/net/ipv4/route.c > +++ b/net/ipv4/route.c > @@ -1872,6 +1872,26 @@ int fib_multipath_hash(const struct net *net, const > struct flowi4 *fl4, > hash_keys.basic.ip_proto = fl4->flowi4_proto; > } > break; > + case 2: > + memset(&hash_keys, 0, sizeof(hash_keys)); > + hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS; > + /* skb is currently provided only when forwarding */ > + if (skb) { > + struct flow_keys keys; > + > + skb_flow_dissect_flow_keys(skb, &keys, 0); > + > + hash_keys.addrs.v4addrs.src = keys.addrs.v4addrs.src; > + hash_keys.addrs.v4addrs.dst = keys.addrs.v4addrs.dst; > + hash_keys.ports.src = keys.ports.src; > + hash_keys.ports.dst = keys.ports.dst; > + hash_keys.basic.ip_proto = keys.basic.ip_proto; This is inconsistent with the code below, you're using ports when we have skb and using only addresses when we don't (host traffic). So either make it L3-only and use addresses or make sure you're using the correct ports as well. > + } else { > + /* Same as case 0 */ > + hash_keys.addrs.v4addrs.src = fl4->saddr; > + hash_keys.addrs.v4addrs.dst = fl4->daddr; > + } > + break; > } > mhash = flow_hash_from_keys(&hash_keys); > > diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c > index 2316c08e9591..e1efc2e62d21 100644 > --- a/net/ipv4/sysctl_net_ipv4.c > +++ b/net/ipv4/sysctl_net_ipv4.c > @@ -960,7 +960,7 @@ static struct ctl_table ipv4_net_table[] = { > .mode = 0644, > .proc_handler = proc_fib_multipath_hash_policy, > .extra1 = &zero, > - .extra2 = &one, > + .extra2 = &two, > }, > #endif > { >