summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/netinet/if_ether.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index 4544fbe..a1fb3ca 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -211,29 +211,41 @@ arprequest(struct ifnet *ifp, struct in_addr *sip, struct in_addr *tip,
struct mbuf *m;
struct arphdr *ah;
struct sockaddr sa;
+ u_char *carpaddr = NULL;
if (sip == NULL) {
- /* XXX don't believe this can happen (or explain why) */
/*
* The caller did not supply a source address, try to find
* a compatible one among those assigned to this interface.
*/
struct ifaddr *ifa;
+ IF_ADDR_RLOCK(ifp);
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
- if (!ifa->ifa_addr ||
- ifa->ifa_addr->sa_family != AF_INET)
+ if (ifa->ifa_addr->sa_family != AF_INET)
continue;
- sip = &SIN(ifa->ifa_addr)->sin_addr;
+
+ if (ifa->ifa_carp) {
+ if ((*carp_iamatch_p)(ifa, &carpaddr) == 0)
+ continue;
+ sip = &IA_SIN(ifa)->sin_addr;
+ } else {
+ carpaddr = NULL;
+ sip = &IA_SIN(ifa)->sin_addr;
+ }
+
if (0 == ((sip->s_addr ^ tip->s_addr) &
- SIN(ifa->ifa_netmask)->sin_addr.s_addr) )
+ IA_MASKSIN(ifa)->sin_addr.s_addr))
break; /* found it. */
}
+ IF_ADDR_RUNLOCK(ifp);
if (sip == NULL) {
printf("%s: cannot find matching address\n", __func__);
return;
}
}
+ if (enaddr == NULL)
+ enaddr = carpaddr ? carpaddr : (u_char *)IF_LLADDR(ifp);
if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
return;
@@ -328,9 +340,7 @@ retry:
*/
if (!(la->la_flags & LLE_STATIC) &&
time_uptime + la->la_preempt > la->la_expire) {
- arprequest(ifp, NULL,
- &SIN(dst)->sin_addr, IF_LLADDR(ifp));
-
+ arprequest(ifp, NULL, &SIN(dst)->sin_addr, NULL);
la->la_preempt--;
}
@@ -406,8 +416,7 @@ retry:
LLE_REMREF(la);
la->la_asked++;
LLE_WUNLOCK(la);
- arprequest(ifp, NULL, &SIN(dst)->sin_addr,
- IF_LLADDR(ifp));
+ arprequest(ifp, NULL, &SIN(dst)->sin_addr, NULL);
return (error);
}
done:
OpenPOWER on IntegriCloud