Commit e4b88884 authored by Natanael Copa's avatar Natanael Copa
Browse files

core/linux-grsec: upgrade to 2.6.29.5

We also move a way from the concept of linux-sources packages.
parent 793bd9b3
From: Timo Teras <timo.teras@iki.fi>
Date: Tue, 20 Jan 2009 01:22:12 +0000 (-0800)
Subject: gre: strict physical device binding
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fdavem%2Fnet-next-2.6.git;a=commitdiff_plain;h=749c10f931923451a4c59b4435d182aa9ae27a4f;hp=57a574993d94671b495cdbe8aeb78b745abfe14f
gre: strict physical device binding
Check the device on receive path and allow otherwise identical devices
as long as the physical device differs.
This is useful for NBMA tunnels, where you want to use different gre IP
for each public IP available via different physical devices.
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 0101521..4a43739 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -164,67 +164,113 @@ static DEFINE_RWLOCK(ipgre_lock);
/* Given src, dst and key, find appropriate for input tunnel. */
-static struct ip_tunnel * ipgre_tunnel_lookup(struct net *net,
+static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev,
__be32 remote, __be32 local,
__be32 key, __be16 gre_proto)
{
+ struct net *net = dev_net(dev);
+ int link = dev->ifindex;
unsigned h0 = HASH(remote);
unsigned h1 = HASH(key);
- struct ip_tunnel *t;
- struct ip_tunnel *t2 = NULL;
+ struct ip_tunnel *t, *sel[4] = { NULL, NULL, NULL, 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;
for (t = ign->tunnels_r_l[h0^h1]; t; t = t->next) {
- if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr) {
- if (t->parms.i_key == key && t->dev->flags & IFF_UP) {
- if (t->dev->type == dev_type)
- return t;
- if (t->dev->type == ARPHRD_IPGRE && !t2)
- t2 = t;
- }
- }
+ if (local != t->parms.iph.saddr ||
+ remote != t->parms.iph.daddr ||
+ key != t->parms.i_key ||
+ !(t->dev->flags & IFF_UP))
+ continue;
+
+ if (t->dev->type != ARPHRD_IPGRE &&
+ t->dev->type != dev_type)
+ continue;
+
+ idx = 0;
+ if (t->parms.link != link)
+ idx |= 1;
+ if (t->dev->type != dev_type)
+ idx |= 2;
+ if (idx == 0)
+ return t;
+ if (sel[idx] == NULL)
+ sel[idx] = t;
}
for (t = ign->tunnels_r[h0^h1]; t; t = t->next) {
- if (remote == t->parms.iph.daddr) {
- if (t->parms.i_key == key && t->dev->flags & IFF_UP) {
- if (t->dev->type == dev_type)
- return t;
- if (t->dev->type == ARPHRD_IPGRE && !t2)
- t2 = t;
- }
- }
+ if (remote != t->parms.iph.daddr ||
+ key != t->parms.i_key ||
+ !(t->dev->flags & IFF_UP))
+ continue;
+
+ if (t->dev->type != ARPHRD_IPGRE &&
+ t->dev->type != dev_type)
+ continue;
+
+ idx = 0;
+ if (t->parms.link != link)
+ idx |= 1;
+ if (t->dev->type != dev_type)
+ idx |= 2;
+ if (idx == 0)
+ return t;
+ if (sel[idx] == NULL)
+ sel[idx] = t;
}
for (t = ign->tunnels_l[h1]; t; t = t->next) {
- if (local == t->parms.iph.saddr ||
- (local == t->parms.iph.daddr &&
- ipv4_is_multicast(local))) {
- if (t->parms.i_key == key && t->dev->flags & IFF_UP) {
- if (t->dev->type == dev_type)
- return t;
- if (t->dev->type == ARPHRD_IPGRE && !t2)
- t2 = t;
- }
- }
+ if ((local != t->parms.iph.saddr &&
+ (local != t->parms.iph.daddr ||
+ !ipv4_is_multicast(local))) ||
+ key != t->parms.i_key ||
+ !(t->dev->flags & IFF_UP))
+ continue;
+
+ if (t->dev->type != ARPHRD_IPGRE &&
+ t->dev->type != dev_type)
+ continue;
+
+ idx = 0;
+ if (t->parms.link != link)
+ idx |= 1;
+ if (t->dev->type != dev_type)
+ idx |= 2;
+ if (idx == 0)
+ return t;
+ if (sel[idx] == NULL)
+ sel[idx] = t;
}
for (t = ign->tunnels_wc[h1]; t; t = t->next) {
- if (t->parms.i_key == key && t->dev->flags & IFF_UP) {
- if (t->dev->type == dev_type)
- return t;
- if (t->dev->type == ARPHRD_IPGRE && !t2)
- t2 = t;
- }
+ if (t->parms.i_key != key ||
+ !(t->dev->flags & IFF_UP))
+ continue;
+
+ if (t->dev->type != ARPHRD_IPGRE &&
+ t->dev->type != dev_type)
+ continue;
+
+ idx = 0;
+ if (t->parms.link != link)
+ idx |= 1;
+ if (t->dev->type != dev_type)
+ idx |= 2;
+ if (idx == 0)
+ return t;
+ if (sel[idx] == NULL)
+ sel[idx] = t;
}
- if (t2)
- return t2;
+ for (idx = 1; idx < ARRAY_SIZE(sel); idx++)
+ if (sel[idx] != NULL)
+ return sel[idx];
- if (ign->fb_tunnel_dev->flags&IFF_UP)
+ if (ign->fb_tunnel_dev->flags & IFF_UP)
return netdev_priv(ign->fb_tunnel_dev);
+
return NULL;
}
@@ -284,6 +330,7 @@ static struct ip_tunnel *ipgre_tunnel_find(struct net *net,
__be32 remote = parms->iph.daddr;
__be32 local = parms->iph.saddr;
__be32 key = parms->i_key;
+ int link = parms->link;
struct ip_tunnel *t, **tp;
struct ipgre_net *ign = net_generic(net, ipgre_net_id);
@@ -291,6 +338,7 @@ static struct ip_tunnel *ipgre_tunnel_find(struct net *net,
if (local == t->parms.iph.saddr &&
remote == t->parms.iph.daddr &&
key == t->parms.i_key &&
+ link == t->parms.link &&
type == t->dev->type)
break;
@@ -421,7 +469,7 @@ static void ipgre_err(struct sk_buff *skb, u32 info)
}
read_lock(&ipgre_lock);
- t = ipgre_tunnel_lookup(dev_net(skb->dev), iph->daddr, iph->saddr,
+ t = ipgre_tunnel_lookup(skb->dev, iph->daddr, iph->saddr,
flags & GRE_KEY ?
*(((__be32 *)p) + (grehlen / 4) - 1) : 0,
p[1]);
@@ -518,7 +566,7 @@ static int ipgre_rcv(struct sk_buff *skb)
gre_proto = *(__be16 *)(h + 2);
read_lock(&ipgre_lock);
- if ((tunnel = ipgre_tunnel_lookup(dev_net(skb->dev),
+ if ((tunnel = ipgre_tunnel_lookup(skb->dev,
iph->saddr, iph->daddr, key,
gre_proto))) {
struct net_device_stats *stats = &tunnel->dev->stats;
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);
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
_flavor=grsec
pkgname=linux-$_flavor
pkgver=2.6.28.9
pkgrel=4
pkgname=linux-${_flavor}
pkgver=2.6.29.5
_kernver=2.6.29
pkgrel=0
pkgdesc="Linux kernel with grsecurity"
url=http://grsecurity.net
arch=i486
makedepends="$pkgname-sources perl"
source="kernelconfig"
subpackages="$pkgname-mod $pkgname-dev"
license=GPL-2
makedepends="$pkgname-sources perl installkernel"
_config=${config:-kernelconfig}
source="ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-$_kernver.tar.bz2
ftp://ftp.kernel.org/pub/linux/kernel/v2.6/patch-$pkgver.bz2
grsecurity-2.1.14-2.6.29.5-200906152045.patch
0001-linux-2.6.28.5-ipgre-strict-binding.patch
0002-linux-2.6.28.5-ipgre-optimize-hash-lookup.patch
net-next-2.6.git-5ef12d98a19254ee5dc851bd83e214b43ec1f725.patch
$_config
"
subpackages="$pkgname-dev"
license="GPL-2"
build() {
mkdir -p "$srcdir/$pkgname"
cd "$srcdir/$pkgname"
cp ../kernelconfig .config
make -C /usr/src/linux-$pkgver-grsec "O=$PWD" HOSTCC="$CC" \
_ksrcdir=/usr/src/linux-${pkgver}-${_flavor}
_abi_release=${pkgver}-${_flavor}
_prepare() {
cd "$srcdir"/linux-$_kernver
if [ "$_kernver" != "$pkgver" ]; then
bunzip2 -c < ../patch-$pkgver.bz2 | patch -p1 || return 1
fi
for i in ../*.patch; do
msg "Applying $i..."
patch -p1 -N < $i || return 1
done
mkdir -p "$srcdir"/build
cp "$srcdir"/$_config "$srcdir"/build/.config
make -C "$_ksrcdir" O="$srcdir"/build HOSTCC="$CC" \
silentoldconfig
}
# this is so we can do: 'abuild menuconfig' to reconfigure kernel
menuconfig() {
_prepare
cd "$srcdir"/build
make menuconfig
cp .config "$startdir"/$_config
}
build() {
_prepare || return 1
cd "$srcdir"/build
make CC="$CC" || return 1
mkdir -p $pkgdir/boot $pkgdir/lib/modules
mkdir -p "$pkgdir"/boot "$pkgdir"/lib/modules
make modules_install install \
INSTALL_MOD_PATH=$pkgdir \
INSTALL_PATH=$pkgdir/boot
cd "$pkgdir"/boot
mv vmlinuz $_flavor
INSTALL_MOD_PATH="$pkgdir" \
INSTALL_PATH="$pkgdir"/boot
# point the build symlink to headers dir
rm -f "$pkgdir"/lib/modules/${_abi_release}/build
ln -sf /usr/src/linux-headers-${_abi_release} \
"$pkgdir"/lib/modules/${_abi_release}/build
}
dev() {
install -Dm644 "$srcdir"/$pkgname/Module.symvers \
"$subpkgdir"/boot/Module.symvers-$_flavor
install -Dm644 "$srcdir/kernelconfig" \
"$subpkgdir"/boot/config-$_flavor
mv "$pkgdir"/boot/System.map "$subpkgdir"/boot/System.map-$_flavor
# create flavored headers ubuntu style
local dir="$subpkgdir"/usr/src/linux-headers-${_abi_release}
mkdir -p "$dir"
cp "$srcdir"/kernelconfig "$dir"/.config
make -j1 -C /usr/src/linux-$pkgver-grsec O="$dir" HOSTCC="$CC" \
silentoldconfig prepare scripts
install -Dm644 "$srcdir"/build/Module.symvers \
"$dir"/Module.symvers
}
md5sums="2b13beaff480758b99eba6cb2191952b kernelconfig"
md5sums="64921b5ff5cdadbccfcd3820f03be7d8 linux-2.6.29.tar.bz2
bd23086872a85c9fd00163e9ab78038a patch-2.6.29.5.bz2
e2e49a250303720b31c4371905c105e3 grsecurity-2.1.14-2.6.29.5-200906152045.patch
7673b4521283ad41434a18ca18b16ad8 0001-linux-2.6.28.5-ipgre-strict-binding.patch
8f405c738b150c532c46eaad5390cca2 0002-linux-2.6.28.5-ipgre-optimize-hash-lookup.patch
ca05fd252783b82e01610e775cf56498 net-next-2.6.git-5ef12d98a19254ee5dc851bd83e214b43ec1f725.patch
d5df3f51ca178a17492beca1419e427e kernelconfig"
This diff is collapsed.
This diff is collapsed.
From: Timo Teras <timo.teras@iki.fi>
Date: Thu, 11 Jun 2009 11:16:28 +0000 (-0700)
Subject: neigh: fix state transition INCOMPLETE->FAILED via Netlink request
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fdavem%2Fnet-next-2.6.git;a=commitdiff_plain;h=5ef12d98a19254ee5dc851bd83e214b43ec1f725;hp=2b85a34e911bf483c27cfdd124aeb1605145dc80
neigh: fix state transition INCOMPLETE->FAILED via Netlink request
The current code errors out the INCOMPLETE neigh entry skb queue only from
the timer if maximum probes have been attempted and there has been no reply.
This also causes the transtion to FAILED state.
However, the neigh entry can be also updated via Netlink to inform that the
address is unavailable. Currently, neigh_update() just stops the timers and
leaves the pending skb's unreleased. This results that the clean up code in
the timer callback is never called, preventing also proper garbage collection.
This fixes neigh_update() to process the pending skb queue immediately if
INCOMPLETE -> FAILED state transtion occurs due to a Netlink request.
Signed-off-by: Timo Teras <timo.teras@iki.fi>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index c54229b..163b4f5 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -771,6 +771,28 @@ static __inline__ int neigh_max_probes(struct neighbour *n)
p->ucast_probes + p->app_probes + p->mcast_probes);
}
+static void neigh_invalidate(struct neighbour *neigh)
+{
+ struct sk_buff *skb;
+
+ NEIGH_CACHE_STAT_INC(neigh->tbl, res_failed);
+ NEIGH_PRINTK2("neigh %p is failed.\n", neigh);
+ neigh->updated = jiffies;
+
+ /* It is very thin place. report_unreachable is very complicated
+ routine. Particularly, it can hit the same neighbour entry!
+
+ So that, we try to be accurate and avoid dead loop. --ANK
+ */
+ while (neigh->nud_state == NUD_FAILED &&
+ (skb = __skb_dequeue(&neigh->arp_queue)) != NULL) {
+ write_unlock(&neigh->lock);
+ neigh->ops->error_report(neigh, skb);
+ write_lock(&neigh->lock);
+ }
+ skb_queue_purge(&neigh->arp_queue);
+}
+
/* Called when a timer expires for a neighbour entry. */
static void neigh_timer_handler(unsigned long arg)
@@ -835,26 +857,9 @@ static void neigh_timer_handler(unsigned long arg)
if ((neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) &&
atomic_read(&neigh->probes) >= neigh_max_probes(neigh)) {
- struct sk_buff *skb;
-
neigh->nud_state = NUD_FAILED;
- neigh->updated = jiffies;
notify = 1;
- NEIGH_CACHE_STAT_INC(neigh->tbl, res_failed);
- NEIGH_PRINTK2("neigh %p is failed.\n", neigh);
-
- /* It is very thin place. report_unreachable is very complicated
- routine. Particularly, it can hit the same neighbour entry!
-
- So that, we try to be accurate and avoid dead loop. --ANK
- */
- while (neigh->nud_state == NUD_FAILED &&
- (skb = __skb_dequeue(&neigh->arp_queue)) != NULL) {
- write_unlock(&neigh->lock);
- neigh->ops->error_report(neigh, skb);
- write_lock(&neigh->lock);
- }
- skb_queue_purge(&neigh->arp_queue);
+ neigh_invalidate(neigh);
}
if (neigh->nud_state & NUD_IN_TIMER) {
@@ -1001,6 +1006,11 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new,
neigh->nud_state = new;
err = 0;
notify = old & NUD_VALID;
+ if ((old & (NUD_INCOMPLETE | NUD_PROBE)) &&
+ (new & NUD_FAILED)) {
+ neigh_invalidate(neigh);
+ notify = 1;
+ }
goto out;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment