From: Juha-Matti Tapio Date: Fri, 29 Feb 2008 04:55:46 +0000 (-0800) Subject: [IPV6]: Fix source address selection for ORCHID addresses X-Git-Tag: v2.6.26-rc1~1138^2~554 X-Git-Url: http://pilppa.com/gitweb/?a=commitdiff_plain;h=99cd07a537bf4c7c954f31611e30064407104410;p=linux-2.6-omap-h63xx.git [IPV6]: Fix source address selection for ORCHID addresses Skip the prefix length matching in source address selection for orchid -> non-orchid addresses. Overlay Routable Cryptographic Hash IDentifiers (RFC 4843, 2001:10::/28) are currenty not globally reachable. Without this check a host with an ORCHID address can end up preferring those over regular addresses when talking to other regular hosts in the 2001::/16 range thus breaking non-orchid connections. Signed-off-by: Juha-Matti Tapio Signed-off-by: David S. Miller --- diff --git a/include/net/ipv6.h b/include/net/ipv6.h index c0c019f72ba..8b05c65415c 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -383,6 +383,16 @@ static inline int ipv6_addr_v4mapped(const struct in6_addr *a) a->s6_addr32[2] == htonl(0x0000ffff)); } +/* + * Check for a RFC 4843 ORCHID address + * (Overlay Routable Cryptographic Hash Identifiers) + */ +static inline int ipv6_addr_orchid(const struct in6_addr *a) +{ + return ((a->s6_addr32[0] & htonl(0xfffffff0)) + == htonl(0x20010010)); +} + /* * find the first different bit between two addresses * length of address must be a multiple of 32bits diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 101e0e70ba2..18e3a9825d8 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -1125,6 +1125,11 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, if (hiscore.rule < 7) hiscore.rule++; #endif + + /* Skip rule 8 for orchid -> non-orchid address pairs. */ + if (ipv6_addr_orchid(&ifa->addr) && !ipv6_addr_orchid(daddr)) + continue; + /* Rule 8: Use longest matching prefix */ if (hiscore.rule < 8) { hiscore.matchlen = ipv6_addr_diff(&ifa_result->addr, daddr);