diff options
Diffstat (limited to 'freebsd/sys/netinet/ip_carp.c')
-rw-r--r-- | freebsd/sys/netinet/ip_carp.c | 26 |
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); |