[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 <jmtapio@verkkotelakka.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index c0c019f..8b05c65 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -384,6 +384,16 @@
}
/*
+ * 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 101e0e7..18e3a98 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1125,6 +1125,11 @@
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);