summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/netinet/ip_carp.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/netinet/ip_carp.c')
-rw-r--r--freebsd/sys/netinet/ip_carp.c26
1 files changed, 15 insertions, 11 deletions
diff --git a/freebsd/sys/netinet/ip_carp.c b/freebsd/sys/netinet/ip_carp.c
index 02a24bb8..30b09198 100644
--- a/freebsd/sys/netinet/ip_carp.c
+++ b/freebsd/sys/netinet/ip_carp.c
@@ -568,13 +568,16 @@ carp6_input(struct mbuf **mp, int *offp, int proto)
}
/* verify that we have a complete carp packet */
- len = m->m_len;
- IP6_EXTHDR_GET(ch, struct carp_header *, m, *offp, sizeof(*ch));
- if (ch == NULL) {
- CARPSTATS_INC(carps_badlen);
- CARP_DEBUG("%s: packet size %u too small\n", __func__, len);
- return (IPPROTO_DONE);
+ if (m->m_len < *offp + sizeof(*ch)) {
+ len = m->m_len;
+ m = m_pullup(m, *offp + sizeof(*ch));
+ if (m == NULL) {
+ CARPSTATS_INC(carps_badlen);
+ CARP_DEBUG("%s: packet size %u too small\n", __func__, len);
+ return (IPPROTO_DONE);
+ }
}
+ ch = (struct carp_header *)(mtod(m, char *) + *offp);
/* verify the CARP checksum */
@@ -1189,7 +1192,7 @@ carp_iamatch6(struct ifnet *ifp, struct in6_addr *taddr)
return (ifa);
}
-caddr_t
+char *
carp_macmatch6(struct ifnet *ifp, struct mbuf *m, const struct in6_addr *taddr)
{
struct ifaddr *ifa;
@@ -1231,14 +1234,15 @@ carp_forus(struct ifnet *ifp, u_char *dhost)
CIF_LOCK(ifp->if_carp);
IFNET_FOREACH_CARP(ifp, sc) {
- CARP_LOCK(sc);
+ /*
+ * CARP_LOCK() is not here, since would protect nothing, but
+ * cause deadlock with if_bridge, calling this under its lock.
+ */
if (sc->sc_state == MASTER && !bcmp(dhost, LLADDR(&sc->sc_addr),
ETHER_ADDR_LEN)) {
- CARP_UNLOCK(sc);
CIF_UNLOCK(ifp->if_carp);
return (1);
}
- CARP_UNLOCK(sc);
}
CIF_UNLOCK(ifp->if_carp);
@@ -1848,7 +1852,7 @@ carp_ioctl(struct ifreq *ifr, u_long cmd, struct thread *td)
carp_carprcp(&carpr, sc, priveleged);
carpr.carpr_count = count;
error = copyout(&carpr,
- (caddr_t)ifr_data_get_ptr(ifr) +
+ (char *)ifr_data_get_ptr(ifr) +
(i * sizeof(carpr)), sizeof(carpr));
if (error) {
CIF_UNLOCK(ifp->if_carp);