From d78628df358a34a7226050da0e4b586834ca037a Mon Sep 17 00:00:00 2001 From: bz Date: Wed, 25 Jul 2012 12:14:39 +0000 Subject: Fix a problem when CARP is enabled on the interface for IPv4 but not for IPv6. The current checks in nd6_nbr.c along with the old version will result in ifa being NULL and subsequently the packet will be dropped. This prevented NS/NA, from working and with that IPv6. Now return the ifa from the carp lookup function in two cases: 1) if the address matches, is a carp address, and we are MASTER (as before), 2) if the address matches but it is not a carp address at all (new). Reported by: Peter Wemm (new Y! FreeBSD cluster, eating our own dogfood) Tested on: New Y! FreeBSD cluster machines Reviewed by: glebius --- sys/netinet/ip_carp.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'sys/netinet') diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c index c5e2758..bc1cc30 100644 --- a/sys/netinet/ip_carp.c +++ b/sys/netinet/ip_carp.c @@ -1027,23 +1027,31 @@ carp_send_na(struct carp_softc *sc) } } +/* + * Returns ifa in case it's a carp address and it is MASTER, or if the address + * matches and is not a carp address. Returns NULL otherwise. + */ struct ifaddr * carp_iamatch6(struct ifnet *ifp, struct in6_addr *taddr) { struct ifaddr *ifa; + ifa = NULL; IF_ADDR_RLOCK(ifp); - IFNET_FOREACH_IFA(ifp, ifa) - if (ifa->ifa_addr->sa_family == AF_INET6 && - ifa->ifa_carp->sc_state == MASTER && - IN6_ARE_ADDR_EQUAL(taddr, IFA_IN6(ifa))) { + TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { + if (ifa->ifa_addr->sa_family != AF_INET6) + continue; + if (!IN6_ARE_ADDR_EQUAL(taddr, IFA_IN6(ifa))) + continue; + if (ifa->ifa_carp && ifa->ifa_carp->sc_state != MASTER) + ifa = NULL; + else ifa_ref(ifa); - IF_ADDR_RUNLOCK(ifp); - return (ifa); - } + break; + } IF_ADDR_RUNLOCK(ifp); - return (NULL); + return (ifa); } caddr_t -- cgit v1.1