Maksim Yevmenkin <e...@freebsd.org> wrote
  in <CAFPOs6pM8qrR72kOtZzO90wYembNrtzw7=ig-nsfudjza7b...@mail.gmail.com>:

em> of course :) we have ipv4 systems in production that make use of
em> getaddrinfo(3) api. when a particular dns name is resolved, and,
em> multiple A records are returned, the results get sorted according to
em> the "default" address selection policy. rfc3484 has a set of rules
em> according to which results should be sorted. all of the rules do not
em> apply in our case, except one - the rule #9. the idea is that ipv4
em> addresses are "converted" to ipv6 addresses and then longest prefix
em> match sorting is applied. in other words, if your system ip address
em> happens to share high bits with the ip address from the A record, the
em> IP address from the A record will always be preferred. of course,
em> longest prefix match is performed  without any extra information such
em> as netmask and/or cidr. it really is just matching high bits of the
em> address.
em>
em> so, what we found out, is that some systems tend to favor a particular
em> ip address (from a bunch of ip addresses returned by name resolution)
em> because 4 high bits were the same. basically, round-robin dns was
em> completely shot.

 Is that issue solved by applying the attached patch and setting
 net.inet6.ip6.longestmatch_mapped=0?

 I do not think it is a good idea to use the empty rule to solve it
 because if the system has to support IPv6 as well the empty rule has
 negative effect.  Adding flag to the IPv4 address line in the policy
 or adding a sysctl sounds a reasonable solution to me.

-- Hiroki
Index: sys/netinet6/in6_proto.c
===================================================================
--- sys/netinet6/in6_proto.c	(revision 238998)
+++ sys/netinet6/in6_proto.c	(working copy)
@@ -587,6 +587,9 @@
 SYSCTL_VNET_INT(_net_inet6_ip6, IPV6CTL_STEALTH, stealth, CTLFLAG_RW,
 	&VNET_NAME(ip6stealth), 0, "");
 #endif
+SYSCTL_VNET_INT(_net_inet6_ip6, IPV6CTL_LONGESTMATCH_MAPPED,
+    longestmatch_mapped, CTLFLAG_RW, &VNET_NAME(ip6_longestmatch_mapped), 0,
+    "Use longest match prefix rule for IPv4-mapped address in addrsel.");

 #ifdef FLOWTABLE
 VNET_DEFINE(int, ip6_output_flowtable_size) = 2048;
Index: sys/netinet6/in6.h
===================================================================
--- sys/netinet6/in6.h	(revision 238998)
+++ sys/netinet6/in6.h	(working copy)
@@ -618,7 +618,8 @@
 					 * receiving IF. */
 #define	IPV6CTL_RFC6204W3	50	/* Accept defroute even when forwarding
 					   enabled */
-#define	IPV6CTL_MAXID		51
+#define	IPV6CTL_LONGESTMATCH_MAPPED	51
+#define	IPV6CTL_MAXID		52
 #endif /* __BSD_VISIBLE */

 /*
Index: sys/netinet6/in6_src.c
===================================================================
--- sys/netinet6/in6_src.c	(revision 238998)
+++ sys/netinet6/in6_src.c	(working copy)
@@ -126,6 +126,7 @@
 #define	V_defaultaddrpolicy		VNET(defaultaddrpolicy)

 VNET_DEFINE(int, ip6_prefer_tempaddr) = 0;
+VNET_DEFINE(int, ip6_longestmatch_mapped) = 1;

 static int selectroute __P((struct sockaddr_in6 *, struct ip6_pktopts *,
 	struct ip6_moptions *, struct route_in6 *, struct ifnet **,
@@ -452,11 +453,13 @@
 		 * a large number so that it is easy to assign smaller numbers
 		 * to more preferred rules.
 		 */
+		if (!IN6_IS_ADDR_V4MAPPED(&dst) || ip6_longestmatch_mapped) {
 		new_matchlen = in6_matchlen(&ia->ia_addr.sin6_addr, &dst);
 		if (best_matchlen < new_matchlen)
 			REPLACE(14);
 		if (new_matchlen < best_matchlen)
 			NEXT(14);
+		}

 		/* Rule 15 is reserved. */

Index: sys/netinet6/ip6_var.h
===================================================================
--- sys/netinet6/ip6_var.h	(revision 238998)
+++ sys/netinet6/ip6_var.h	(working copy)
@@ -357,6 +357,9 @@
 					 * zone when unspecified */
 #define	V_ip6_use_defzone		VNET(ip6_use_defzone)

+VNET_DECLARE(int, ip6_longestmatch_mapped); /* Use longest match for addrsel */
+#define	V_ip6_longestmatch_mapped	VNET(ip6_longestmatch_mapped)
+
 VNET_DECLARE (struct pfil_head, inet6_pfil_hook);	/* packet filter hooks */
 #define	V_inet6_pfil_hook	VNET(inet6_pfil_hook)
 #ifdef IPSTEALTH

Attachment: pgpyY6nweGltr.pgp
Description: PGP signature

Reply via email to