summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet6/in6.c35
1 files changed, 33 insertions, 2 deletions
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index cbc7ccc9bcd..f26eed31bdd 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in6.c,v 1.241 2020/08/04 17:05:52 anton Exp $ */
+/* $OpenBSD: in6.c,v 1.242 2020/08/07 18:09:16 florian Exp $ */
/* $KAME: in6.c,v 1.372 2004/06/14 08:14:21 itojun Exp $ */
/*
@@ -1498,7 +1498,38 @@ in6_ifawithscope(struct ifnet *oifp, struct in6_addr *dst, u_int rdomain)
continue;
#endif
goto replace;
- }
+ } else if (tlen < blen)
+ continue;
+
+ /*
+ * If the eight rules fail to choose a single address,
+ * the tiebreaker is implementation-specific.
+ */
+
+ /* Prefer address with highest pltime. */
+ if (ia6_best->ia6_updatetime +
+ ia6_best->ia6_lifetime.ia6t_pltime <
+ ifatoia6(ifa)->ia6_updatetime +
+ ifatoia6(ifa)->ia6_lifetime.ia6t_pltime)
+ goto replace;
+ else if (ia6_best->ia6_updatetime +
+ ia6_best->ia6_lifetime.ia6t_pltime >
+ ifatoia6(ifa)->ia6_updatetime +
+ ifatoia6(ifa)->ia6_lifetime.ia6t_pltime)
+ continue;
+
+ /* Prefer address with highest vltime. */
+ if (ia6_best->ia6_updatetime +
+ ia6_best->ia6_lifetime.ia6t_vltime <
+ ifatoia6(ifa)->ia6_updatetime +
+ ifatoia6(ifa)->ia6_lifetime.ia6t_vltime)
+ goto replace;
+ else if (ia6_best->ia6_updatetime +
+ ia6_best->ia6_lifetime.ia6t_vltime >
+ ifatoia6(ifa)->ia6_updatetime +
+ ifatoia6(ifa)->ia6_lifetime.ia6t_vltime)
+ continue;
+
continue;
replace:
ia6_best = ifatoia6(ifa);