Add a check for our own advertisements. This is due to non-simplex

interfaces which received the packets they have just sent.

From: OpenBSD (rev. 1.124)
ok: christos@
This commit is contained in:
liamjfoy 2006-05-24 13:39:37 +00:00
parent 1a4039e6b0
commit d8d9494bf9

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip_carp.c,v 1.1 2006/05/18 09:05:51 liamjfoy Exp $ */
/* $NetBSD: ip_carp.c,v 1.2 2006/05/24 13:39:37 liamjfoy Exp $ */
/* $OpenBSD: ip_carp.c,v 1.113 2005/11/04 08:11:54 mcbride Exp $ */
/*
@ -591,6 +591,48 @@ carp_proto_input_c(struct mbuf *m, struct carp_header *ch, sa_family_t af)
return;
}
/*
* Check if our own advertisement was duplicated
* from a non simplex interface.
* XXX If there is no address on our physical interface
* there is no way to distinguish our ads from the ones
* another carp host might have sent us.
*/
if ((sc->sc_carpdev->if_flags & IFF_SIMPLEX) == 0) {
struct sockaddr sa;
struct ifaddr *ifa;
bzero(&sa, sizeof(sa));
sa.sa_family = af;
ifa = ifaof_ifpforaddr(&sa, sc->sc_carpdev);
if (ifa && af == AF_INET) {
struct ip *ip = mtod(m, struct ip *);
if (ip->ip_src.s_addr ==
ifatoia(ifa)->ia_addr.sin_addr.s_addr) {
m_freem(m);
return;
}
}
#ifdef INET6
if (ifa && af == AF_INET6) {
struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
struct in6_addr in6_src, in6_found;
in6_src = ip6->ip6_src;
in6_found = ifatoia6(ifa)->ia_addr.sin6_addr;
if (IN6_IS_ADDR_LINKLOCAL(&in6_src))
in6_src.s6_addr16[1] = 0;
if (IN6_IS_ADDR_LINKLOCAL(&in6_found))
in6_found.s6_addr16[1] = 0;
if (IN6_ARE_ADDR_EQUAL(&in6_src, &in6_found)) {
m_freem(m);
return;
}
}
#endif /* INET6 */
}
microtime(&sc->sc_if.if_lastchange);
sc->sc_if.if_ipackets++;
sc->sc_if.if_ibytes += m->m_pkthdr.len;