summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Sperling <stsp@cvs.openbsd.org>2014-10-22 09:48:20 +0000
committerStefan Sperling <stsp@cvs.openbsd.org>2014-10-22 09:48:20 +0000
commit13528a07bd5f38b52167218e746dfa4b8ef35a3d (patch)
treed1b38f4e48be237d808aa9655eff863633b31ae5
parent115f10b364f9e3bb1f68545fdfcee38d048ef2af (diff)
Introduce a special hack for carp during IPv6 source address selection:
If there is a tie then a carp interface is not allowed to win even if it has an address with a longer bitwise match. This allows reliable IPv6 communication between carp master and backup across a shared IPv6 subnet. Consider the carp address 2001:DB8:10::14, which is configured on firewall A (in carp master state) and firewall B (in carp backup state), each of which has another address in the same prefix on a non-carp interface (A has 2001:DB8:10::1 and B has 2001:DB8:10::11). In this setup, A would use 2001:DB8:10::14 as source address when sending neighbour solicitations to B. Since 2001:DB8:10::14 is a local address from B's point of view, B never replied to the neighbour solicitations sent by A. With this change A uses 2001:DB8:10::1 as source address instead. ok mpi@
-rw-r--r--sys/netinet6/in6.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index 98ef79db83a..2a33e6848b0 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in6.c,v 1.142 2014/10/14 09:52:26 mpi Exp $ */
+/* $OpenBSD: in6.c,v 1.143 2014/10/22 09:48:19 stsp Exp $ */
/* $KAME: in6.c,v 1.372 2004/06/14 08:14:21 itojun Exp $ */
/*
@@ -2027,8 +2027,26 @@ in6_ifawithscope(struct ifnet *oifp, struct in6_addr *dst, u_int rdomain)
}
tlen = in6_matchlen(IFA_IN6(ifa), dst);
matchcmp = tlen - blen;
- if (matchcmp > 0) /* (8) */
+ if (matchcmp > 0) { /* (8) */
+#if NCARP > 0
+ /*
+ * Don't let carp interfaces win a tie against
+ * the output interface based on matchlen.
+ * We should only use a carp address if no
+ * other interface has a usable address.
+ * Otherwise, when communicating from a carp
+ * master to a carp slave, the slave won't
+ * respond since the carp address is also
+ * configured as a local address on the slave.
+ * Note that carp interfaces in backup state
+ * were already skipped above.
+ */
+ if (ifp->if_type == IFT_CARP &&
+ oifp->if_type != IFT_CARP)
+ continue;
+#endif
goto replace;
+ }
if (matchcmp < 0) /* (9) */
continue;
if (oifp == ifp) /* (a) */