diff options
author | Stephen Suryaputra <ssuryaextr@gmail.com> | 2019-07-06 10:55:17 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-07-08 19:37:29 -0400 |
commit | 828b2b442145cbe94fe3ca0e34a47f64b0f322ef (patch) | |
tree | 6682d5ea1e89a729bac348df03092808555f827a | |
parent | faf5577f2498cea23011b5c785ef853ded22700b (diff) |
ipv4: Multipath hashing on inner L3 needs to consider inner IPv6 pkts
Commit 363887a2cdfe ("ipv4: Support multipath hashing on inner IP pkts
for GRE tunnel") supports multipath policy value of 2, Layer 3 or inner
Layer 3 if present, but it only considers inner IPv4. There is a use
case of IPv6 is tunneled by IPv4 GRE, thus add the ability to hash on
inner IPv6 addresses.
Fixes: 363887a2cdfe ("ipv4: Support multipath hashing on inner IP pkts for GRE tunnel")
Signed-off-by: Stephen Suryaputra <ssuryaextr@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/ipv4/route.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index dc1f510a7c81..abaa7f9371e5 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -1964,17 +1964,30 @@ int fib_multipath_hash(const struct net *net, const struct flowi4 *fl4, | |||
1964 | break; | 1964 | break; |
1965 | case 2: | 1965 | case 2: |
1966 | memset(&hash_keys, 0, sizeof(hash_keys)); | 1966 | memset(&hash_keys, 0, sizeof(hash_keys)); |
1967 | hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS; | ||
1968 | /* skb is currently provided only when forwarding */ | 1967 | /* skb is currently provided only when forwarding */ |
1969 | if (skb) { | 1968 | if (skb) { |
1970 | struct flow_keys keys; | 1969 | struct flow_keys keys; |
1971 | 1970 | ||
1972 | skb_flow_dissect_flow_keys(skb, &keys, 0); | 1971 | skb_flow_dissect_flow_keys(skb, &keys, 0); |
1973 | 1972 | /* Inner can be v4 or v6 */ | |
1974 | hash_keys.addrs.v4addrs.src = keys.addrs.v4addrs.src; | 1973 | if (keys.control.addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) { |
1975 | hash_keys.addrs.v4addrs.dst = keys.addrs.v4addrs.dst; | 1974 | hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS; |
1975 | hash_keys.addrs.v4addrs.src = keys.addrs.v4addrs.src; | ||
1976 | hash_keys.addrs.v4addrs.dst = keys.addrs.v4addrs.dst; | ||
1977 | } else if (keys.control.addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS) { | ||
1978 | hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS; | ||
1979 | hash_keys.addrs.v6addrs.src = keys.addrs.v6addrs.src; | ||
1980 | hash_keys.addrs.v6addrs.dst = keys.addrs.v6addrs.dst; | ||
1981 | hash_keys.tags.flow_label = keys.tags.flow_label; | ||
1982 | hash_keys.basic.ip_proto = keys.basic.ip_proto; | ||
1983 | } else { | ||
1984 | /* Same as case 0 */ | ||
1985 | hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS; | ||
1986 | ip_multipath_l3_keys(skb, &hash_keys); | ||
1987 | } | ||
1976 | } else { | 1988 | } else { |
1977 | /* Same as case 0 */ | 1989 | /* Same as case 0 */ |
1990 | hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS; | ||
1978 | hash_keys.addrs.v4addrs.src = fl4->saddr; | 1991 | hash_keys.addrs.v4addrs.src = fl4->saddr; |
1979 | hash_keys.addrs.v4addrs.dst = fl4->daddr; | 1992 | hash_keys.addrs.v4addrs.dst = fl4->daddr; |
1980 | } | 1993 | } |