summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Suryaputra <ssuryaextr@gmail.com>2019-06-13 14:38:58 -0400
committerDavid S. Miller <davem@davemloft.net>2019-06-14 22:42:35 -0400
commit363887a2cdfeb6af52a9b78d84697662adf6f8d5 (patch)
treedeae85756a29cfb317bf71a5b473ed71861c7338
parent31c03aef9bc22a64a8324d650ca4198819ef3a33 (diff)
ipv4: Support multipath hashing on inner IP pkts for GRE tunnel
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). v3: Remove accidental inclusion of ports in the hash keys and clarify the documentation (Nikolay Alexandrov). Signed-off-by: Stephen Suryaputra <ssuryaextr@gmail.com> Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--Documentation/networking/ip-sysctl.txt1
-rw-r--r--net/ipv4/route.c17
-rw-r--r--net/ipv4/sysctl_net_ipv4.c2
3 files changed, 19 insertions, 1 deletions
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index f4b1043e92ed..dc473354d90b 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -80,6 +80,7 @@ fib_multipath_hash_policy - INTEGER
80 Possible values: 80 Possible values:
81 0 - Layer 3 81 0 - Layer 3
82 1 - Layer 4 82 1 - Layer 4
83 2 - Layer 3 or inner Layer 3 if present
83 84
84fib_sync_mem - UNSIGNED INTEGER 85fib_sync_mem - UNSIGNED INTEGER
85 Amount of dirty memory from fib entries that can be backlogged before 86 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 0700a7d59811..66cbe8a7a168 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1930,6 +1930,23 @@ int fib_multipath_hash(const struct net *net, const struct flowi4 *fl4,
1930 hash_keys.basic.ip_proto = fl4->flowi4_proto; 1930 hash_keys.basic.ip_proto = fl4->flowi4_proto;
1931 } 1931 }
1932 break; 1932 break;
1933 case 2:
1934 memset(&hash_keys, 0, sizeof(hash_keys));
1935 hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
1936 /* skb is currently provided only when forwarding */
1937 if (skb) {
1938 struct flow_keys keys;
1939
1940 skb_flow_dissect_flow_keys(skb, &keys, 0);
1941
1942 hash_keys.addrs.v4addrs.src = keys.addrs.v4addrs.src;
1943 hash_keys.addrs.v4addrs.dst = keys.addrs.v4addrs.dst;
1944 } else {
1945 /* Same as case 0 */
1946 hash_keys.addrs.v4addrs.src = fl4->saddr;
1947 hash_keys.addrs.v4addrs.dst = fl4->daddr;
1948 }
1949 break;
1933 } 1950 }
1934 mhash = flow_hash_from_keys(&hash_keys); 1951 mhash = flow_hash_from_keys(&hash_keys);
1935 1952
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 90f09e47198b..0edfa810f9b9 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -1008,7 +1008,7 @@ static struct ctl_table ipv4_net_table[] = {
1008 .mode = 0644, 1008 .mode = 0644,
1009 .proc_handler = proc_fib_multipath_hash_policy, 1009 .proc_handler = proc_fib_multipath_hash_policy,
1010 .extra1 = &zero, 1010 .extra1 = &zero,
1011 .extra2 = &one, 1011 .extra2 = &two,
1012 }, 1012 },
1013#endif 1013#endif
1014 { 1014 {