diff options
author | glebius <glebius@FreeBSD.org> | 2005-03-09 10:00:01 +0000 |
---|---|---|
committer | glebius <glebius@FreeBSD.org> | 2005-03-09 10:00:01 +0000 |
commit | 41e08b3800138e174d79cbe2843b26384aa5ddb9 (patch) | |
tree | 71c3c4946945fd7b3587dd004dd7163076b00b23 /sys/netinet | |
parent | 283c3a89b1672ff6529400464c983de692e3d1ba (diff) | |
download | FreeBSD-src-41e08b3800138e174d79cbe2843b26384aa5ddb9.zip FreeBSD-src-41e08b3800138e174d79cbe2843b26384aa5ddb9.tar.gz |
Make ARP do not complain about wrong interface if correct interface
is a carp one and address matched it.
Reviewed by: brooks
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/if_ether.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c index 1bc1d06..fff7cf8 100644 --- a/sys/netinet/if_ether.c +++ b/sys/netinet/if_ether.c @@ -553,6 +553,7 @@ in_arpinput(m) u_int8_t *enaddr = NULL; int op, rif_len; int req_len; + int carp_match = 0; req_len = arphdr_len2(ifp->if_addrlen, sizeof(struct in_addr)); if (m->m_len < req_len && (m = m_pullup(m, req_len)) == NULL) { @@ -574,14 +575,19 @@ in_arpinput(m) * request for the virtual host ip. * XXX: This is really ugly! */ - LIST_FOREACH(ia, INADDR_HASH(itaddr.s_addr), ia_hash) - if ((do_bridge || (ia->ia_ifp == ifp) + LIST_FOREACH(ia, INADDR_HASH(itaddr.s_addr), ia_hash) { + if ((do_bridge || (ia->ia_ifp == ifp)) && + itaddr.s_addr == ia->ia_addr.sin_addr.s_addr) + goto match; #ifdef DEV_CARP - || (ifp->if_carp - && carp_iamatch(ifp->if_carp, ia, &isaddr, &enaddr)) -#endif - ) && itaddr.s_addr == ia->ia_addr.sin_addr.s_addr) + if (ifp->if_carp != NULL && + carp_iamatch(ifp->if_carp, ia, &isaddr, &enaddr) && + itaddr.s_addr == ia->ia_addr.sin_addr.s_addr) { + carp_match = 1; goto match; + } +#endif + } LIST_FOREACH(ia, INADDR_HASH(isaddr.s_addr), ia_hash) if ((do_bridge || (ia->ia_ifp == ifp)) && isaddr.s_addr == ia->ia_addr.sin_addr.s_addr) @@ -631,7 +637,8 @@ match: la = arplookup(isaddr.s_addr, itaddr.s_addr == myaddr.s_addr, 0); if (la && (rt = la->la_rt) && (sdl = SDL(rt->rt_gateway))) { /* the following is not an error when doing bridging */ - if (!do_bridge && rt->rt_ifp != ifp) { + if (!do_bridge && rt->rt_ifp != ifp && + !(ifp->if_type == IFT_CARP && carp_match)) { if (log_arp_wrong_iface) log(LOG_ERR, "arp: %s is on %s but got reply from %*D on %s\n", inet_ntoa(isaddr), |