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
This commit is contained in:
Bjoern A. Zeeb 2012-07-25 12:14:39 +00:00
parent d01755ed20
commit 8253dcabe7
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=238769

View File

@ -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