diff options
author | Stefan Sperling <stsp@cvs.openbsd.org> | 2014-10-22 09:48:20 +0000 |
---|---|---|
committer | Stefan Sperling <stsp@cvs.openbsd.org> | 2014-10-22 09:48:20 +0000 |
commit | 13528a07bd5f38b52167218e746dfa4b8ef35a3d (patch) | |
tree | d1b38f4e48be237d808aa9655eff863633b31ae5 /sys | |
parent | 115f10b364f9e3bb1f68545fdfcee38d048ef2af (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@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/netinet6/in6.c | 22 |
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) */ |