Commit a32f6939 authored by Natanael Copa's avatar Natanael Copa

main/linux-grsec: fix for multicast

parent c558cedf
......@@ -4,7 +4,7 @@ _flavor=grsec
pkgname=linux-${_flavor}
pkgver=2.6.38.2
_kernver=2.6.38
pkgrel=2
pkgrel=3
pkgdesc="Linux kernel with grsecurity"
url=http://grsecurity.net
depends="mkinitfs linux-firmware"
......@@ -17,6 +17,7 @@ source="ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-$_kernver.tar.bz2
grsecurity-2.2.2-2.6.38.2-201103281752.patch
0004-arp-flush-arp-cache-on-device-change.patch
net-gre-provide-multicast-mappings-for-ipv4-and-ipv6.patch
kernelconfig.x86
kernelconfig.x86_64
......@@ -139,5 +140,6 @@ md5sums="7d471477bfa67546f902da62227fa976 linux-2.6.38.tar.bz2
599badab31c4920d4122133208c810d7 patch-2.6.38.2.bz2
fac4f5fb386192c544fae27db6db18a7 grsecurity-2.2.2-2.6.38.2-201103281752.patch
776adeeb5272093574f8836c5037dd7d 0004-arp-flush-arp-cache-on-device-change.patch
aa1b82da0cabfb41c5e6da5bddf60bab net-gre-provide-multicast-mappings-for-ipv4-and-ipv6.patch
47ff0feca681cd53a037b7f5c9b46c3d kernelconfig.x86
2d70a4c38d97ca1a5280ca8d4e535628 kernelconfig.x86_64"
From: Timo Teräs <timo.teras@iki.fi>
Date: Mon, 28 Mar 2011 22:40:53 +0000 (+0000)
Subject: net: gre: provide multicast mappings for ipv4 and ipv6
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fdavem%2Fnet-2.6.git;a=commitdiff_plain;h=93ca3bb5df9bc8b2c60485e1cc6507c3d7c8e1fa
net: gre: provide multicast mappings for ipv4 and ipv6
My commit 6d55cb91a0020ac0 (gre: fix hard header destination
address checking) broke multicast.
The reason is that ip_gre used to get ipgre_header() calls with
zero destination if we have NOARP or multicast destination. Instead
the actual target was decided at ipgre_tunnel_xmit() time based on
per-protocol dissection.
Instead of allowing the "abuse" of ->header() calls with invalid
destination, this creates multicast mappings for ip_gre. This also
fixes "ip neigh show nud noarp" to display the proper multicast
mappings used by the gre device.
Reported-by: Doug Kehn <rdkehn@yahoo.com>
Signed-off-by: Timo Teräs <timo.teras@iki.fi>
Acked-by: Doug Kehn <rdkehn@yahoo.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h
index 04977ee..fccc218 100644
--- a/include/net/if_inet6.h
+++ b/include/net/if_inet6.h
@@ -286,5 +286,21 @@ static inline void ipv6_ib_mc_map(const struct in6_addr *addr,
buf[9] = broadcast[9];
memcpy(buf + 10, addr->s6_addr + 6, 10);
}
+
+static inline int ipv6_ipgre_mc_map(const struct in6_addr *addr,
+ const unsigned char *broadcast, char *buf)
+{
+ if ((broadcast[0] | broadcast[1] | broadcast[2] | broadcast[3]) != 0) {
+ memcpy(buf, broadcast, 4);
+ } else {
+ /* v4mapped? */
+ if ((addr->s6_addr32[0] | addr->s6_addr32[1] |
+ (addr->s6_addr32[2] ^ htonl(0x0000ffff))) != 0)
+ return -EINVAL;
+ memcpy(buf, &addr->s6_addr32[3], 4);
+ }
+ return 0;
+}
+
#endif
#endif
diff --git a/include/net/ip.h b/include/net/ip.h
index a4f6311..7c41658 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -339,6 +339,14 @@ static inline void ip_ib_mc_map(__be32 naddr, const unsigned char *broadcast, ch
buf[16] = addr & 0x0f;
}
+static inline void ip_ipgre_mc_map(__be32 naddr, const unsigned char *broadcast, char *buf)
+{
+ if ((broadcast[0] | broadcast[1] | broadcast[2] | broadcast[3]) != 0)
+ memcpy(buf, broadcast, 4);
+ else
+ memcpy(buf, &naddr, sizeof(naddr));
+}
+
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
#include <linux/ipv6.h>
#endif
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 090d273..1b74d3b 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -215,6 +215,9 @@ int arp_mc_map(__be32 addr, u8 *haddr, struct net_device *dev, int dir)
case ARPHRD_INFINIBAND:
ip_ib_mc_map(addr, dev->broadcast, haddr);
return 0;
+ case ARPHRD_IPGRE:
+ ip_ipgre_mc_map(addr, dev->broadcast, haddr);
+ return 0;
default:
if (dir) {
memcpy(haddr, dev->broadcast, dev->addr_len);
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 0e49c9d..92f952d 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -341,6 +341,8 @@ int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int d
case ARPHRD_INFINIBAND:
ipv6_ib_mc_map(addr, dev->broadcast, buf);
return 0;
+ case ARPHRD_IPGRE:
+ return ipv6_ipgre_mc_map(addr, dev->broadcast, buf);
default:
if (dir) {
memcpy(buf, dev->broadcast, dev->addr_len);
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