summaryrefslogtreecommitdiffstats
path: root/main/linux-grsec/0002-linux-2.6.28.5-ipgre-optimize-hash-lookup.patch
diff options
context:
space:
mode:
Diffstat (limited to 'main/linux-grsec/0002-linux-2.6.28.5-ipgre-optimize-hash-lookup.patch')
-rw-r--r--main/linux-grsec/0002-linux-2.6.28.5-ipgre-optimize-hash-lookup.patch140
1 files changed, 140 insertions, 0 deletions
diff --git a/main/linux-grsec/0002-linux-2.6.28.5-ipgre-optimize-hash-lookup.patch b/main/linux-grsec/0002-linux-2.6.28.5-ipgre-optimize-hash-lookup.patch
new file mode 100644
index 00000000..fbfef33b
--- /dev/null
+++ b/main/linux-grsec/0002-linux-2.6.28.5-ipgre-optimize-hash-lookup.patch
@@ -0,0 +1,140 @@
+From: Timo Teras <timo.teras@iki.fi>
+Date: Tue, 27 Jan 2009 04:56:10 +0000 (-0800)
+Subject: gre: optimize hash lookup
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fdavem%2Fnet-next-2.6.git;a=commitdiff_plain;h=afcf12422ec8236dc8b9238fef7a475876eea8da;hp=3eacdf58c2c0b9507afedfc19108e98b992c31e4
+
+gre: optimize hash lookup
+
+Instead of keeping candidate tunnel device from all categories,
+keep only one candidate with best score. This optimizes stack
+usage and speeds up exit code.
+
+Signed-off-by: Timo Teras <timo.teras@iki.fi>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+
+diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
+index 4a43739..07a188a 100644
+--- a/net/ipv4/ip_gre.c
++++ b/net/ipv4/ip_gre.c
+@@ -172,11 +172,11 @@ static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev,
+ int link = dev->ifindex;
+ unsigned h0 = HASH(remote);
+ unsigned h1 = HASH(key);
+- struct ip_tunnel *t, *sel[4] = { NULL, NULL, NULL, NULL };
++ struct ip_tunnel *t, *cand = NULL;
+ struct ipgre_net *ign = net_generic(net, ipgre_net_id);
+ int dev_type = (gre_proto == htons(ETH_P_TEB)) ?
+ ARPHRD_ETHER : ARPHRD_IPGRE;
+- int idx;
++ int score, cand_score = 4;
+
+ for (t = ign->tunnels_r_l[h0^h1]; t; t = t->next) {
+ if (local != t->parms.iph.saddr ||
+@@ -189,15 +189,18 @@ static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev,
+ t->dev->type != dev_type)
+ continue;
+
+- idx = 0;
++ score = 0;
+ if (t->parms.link != link)
+- idx |= 1;
++ score |= 1;
+ if (t->dev->type != dev_type)
+- idx |= 2;
+- if (idx == 0)
++ score |= 2;
++ if (score == 0)
+ return t;
+- if (sel[idx] == NULL)
+- sel[idx] = t;
++
++ if (score < cand_score) {
++ cand = t;
++ cand_score = score;
++ }
+ }
+
+ for (t = ign->tunnels_r[h0^h1]; t; t = t->next) {
+@@ -210,15 +213,18 @@ static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev,
+ t->dev->type != dev_type)
+ continue;
+
+- idx = 0;
++ score = 0;
+ if (t->parms.link != link)
+- idx |= 1;
++ score |= 1;
+ if (t->dev->type != dev_type)
+- idx |= 2;
+- if (idx == 0)
++ score |= 2;
++ if (score == 0)
+ return t;
+- if (sel[idx] == NULL)
+- sel[idx] = t;
++
++ if (score < cand_score) {
++ cand = t;
++ cand_score = score;
++ }
+ }
+
+ for (t = ign->tunnels_l[h1]; t; t = t->next) {
+@@ -233,15 +239,18 @@ static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev,
+ t->dev->type != dev_type)
+ continue;
+
+- idx = 0;
++ score = 0;
+ if (t->parms.link != link)
+- idx |= 1;
++ score |= 1;
+ if (t->dev->type != dev_type)
+- idx |= 2;
+- if (idx == 0)
++ score |= 2;
++ if (score == 0)
+ return t;
+- if (sel[idx] == NULL)
+- sel[idx] = t;
++
++ if (score < cand_score) {
++ cand = t;
++ cand_score = score;
++ }
+ }
+
+ for (t = ign->tunnels_wc[h1]; t; t = t->next) {
+@@ -253,20 +262,22 @@ static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev,
+ t->dev->type != dev_type)
+ continue;
+
+- idx = 0;
++ score = 0;
+ if (t->parms.link != link)
+- idx |= 1;
++ score |= 1;
+ if (t->dev->type != dev_type)
+- idx |= 2;
+- if (idx == 0)
++ score |= 2;
++ if (score == 0)
+ return t;
+- if (sel[idx] == NULL)
+- sel[idx] = t;
++
++ if (score < cand_score) {
++ cand = t;
++ cand_score = score;
++ }
+ }
+
+- for (idx = 1; idx < ARRAY_SIZE(sel); idx++)
+- if (sel[idx] != NULL)
+- return sel[idx];
++ if (cand != NULL)
++ return cand;
+
+ if (ign->fb_tunnel_dev->flags & IFF_UP)
+ return netdev_priv(ign->fb_tunnel_dev);