Date: Fri, 20 Jan 2017 00:15:11 +0000 (UTC) From: Josh Paetzel <jpaetzel@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r312444 - stable/10/sys/netinet Message-ID: <201701200015.v0K0FBqA016412@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jpaetzel Date: Fri Jan 20 00:15:11 2017 New Revision: 312444 URL: https://svnweb.freebsd.org/changeset/base/312444 Log: Revert MFC of 310847 and 310864 Requested by glebius who had questions about the original head commit that I didn't see. Modified: stable/10/sys/netinet/ip_carp.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/netinet/ip_carp.c ============================================================================== --- stable/10/sys/netinet/ip_carp.c Fri Jan 20 00:02:11 2017 (r312443) +++ stable/10/sys/netinet/ip_carp.c Fri Jan 20 00:15:11 2017 (r312444) @@ -573,96 +573,27 @@ carp6_input(struct mbuf **mp, int *offp, } #endif /* INET6 */ -/* - * This routine should not be necessary at all, but some switches - * (VMWare ESX vswitches) can echo our own packets back at us, - * and we must ignore them or they will cause us to drop out of - * MASTER mode. - * - * We cannot catch all cases of network loops. Instead, what we - * do here is catch any packet that arrives with a carp header - * with a VHID of 0, that comes from an address that is our own. - * These packets are by definition "from us" (even if they are from - * a misconfigured host that is pretending to be us). - * - * The VHID test is outside this mini-function. - */ -static int -carp_source_is_self(struct mbuf *m, struct ifaddr *ifa, sa_family_t af) -{ -#ifdef INET - struct ip *ip4; - struct in_addr in4; -#endif -#ifdef INET6 - struct ip6_hdr *ip6; - struct in6_addr in6; -#endif - - switch (af) { -#ifdef INET - case AF_INET: - ip4 = mtod(m, struct ip *); - in4 = ifatoia(ifa)->ia_addr.sin_addr; - return (in4.s_addr == ip4->ip_src.s_addr); -#endif -#ifdef INET6 - case AF_INET6: - ip6 = mtod(m, struct ip6_hdr *); - in6 = ifatoia6(ifa)->ia_addr.sin6_addr; - return (memcmp(&in6, &ip6->ip6_src, sizeof(in6)) == 0); -#endif - default: - break; - } - return (0); -} - static void carp_input_c(struct mbuf *m, struct carp_header *ch, sa_family_t af) { struct ifnet *ifp = m->m_pkthdr.rcvif; - struct ifaddr *ifa, *match; + struct ifaddr *ifa; struct carp_softc *sc; uint64_t tmp_counter; struct timeval sc_tv, ch_tv; - int error; - /* - * Verify that the VHID is valid on the receiving interface. - * - * There should be just one match. If there are none - * the VHID is not valid and we drop the packet. If - * there are multiple VHID matches, take just the first - * one, for compatibility with previous code. While we're - * scanning, check for obvious loops in the network topology - * (these should never happen, and as noted above, we may - * miss real loops; this is just a double-check). - */ + /* verify that the VHID is valid on the receiving interface */ IF_ADDR_RLOCK(ifp); - error = 0; - match = NULL; - IFNET_FOREACH_IFA(ifp, ifa) { - if (match == NULL && ifa->ifa_carp != NULL && - ifa->ifa_addr->sa_family == af && - ifa->ifa_carp->sc_vhid == ch->carp_vhid) - match = ifa; - if (ch->carp_vhid == 0 && carp_source_is_self(m, ifa, af)) - error = ELOOP; - } - ifa = error ? NULL : match; - if (ifa != NULL) - ifa_ref(ifa); + IFNET_FOREACH_IFA(ifp, ifa) + if (ifa->ifa_addr->sa_family == af && + ifa->ifa_carp->sc_vhid == ch->carp_vhid) { + ifa_ref(ifa); + break; + } IF_ADDR_RUNLOCK(ifp); if (ifa == NULL) { - if (error == ELOOP) { - CARP_DEBUG("dropping looped packet on interface %s\n", - ifp->if_xname); - CARPSTATS_INC(carps_badif); /* ??? */ - } else { - CARPSTATS_INC(carps_badvhid); - } + CARPSTATS_INC(carps_badvhid); m_freem(m); return; } @@ -858,41 +789,12 @@ carp_send_ad_error(struct carp_softc *sc } } -/* - * Pick the best ifaddr on the given ifp for sending CARP - * advertisements. - * - * "Best" here is defined by ifa_preferred(). This function is much - * much like ifaof_ifpforaddr() except that we just use ifa_preferred(). - * - * (This could be simplified to return the actual address, except that - * it has a different format in AF_INET and AF_INET6.) - */ -static struct ifaddr * -carp_best_ifa(int af, struct ifnet *ifp) -{ - struct ifaddr *ifa, *best; - - if (af >= AF_MAX) - return (NULL); - best = NULL; - IF_ADDR_RLOCK(ifp); - TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { - if (ifa->ifa_addr->sa_family == af && - (best == NULL || ifa_preferred(best, ifa))) - best = ifa; - } - IF_ADDR_RUNLOCK(ifp); - if (best != NULL) - ifa_ref(best); - return (best); -} - static void carp_send_ad_locked(struct carp_softc *sc) { struct carp_header ch; struct timeval tv; + struct sockaddr sa; struct ifaddr *ifa; struct carp_header *ch_ptr; struct mbuf *m; @@ -941,7 +843,9 @@ carp_send_ad_locked(struct carp_softc *s ip->ip_p = IPPROTO_CARP; ip->ip_sum = 0; - ifa = carp_best_ifa(AF_INET, sc->sc_carpdev); + bzero(&sa, sizeof(sa)); + sa.sa_family = AF_INET; + ifa = ifaof_ifpforaddr(&sa, sc->sc_carpdev); if (ifa != NULL) { ip->ip_src.s_addr = ifatoia(ifa)->ia_addr.sin_addr.s_addr; @@ -985,9 +889,11 @@ carp_send_ad_locked(struct carp_softc *s ip6->ip6_vfc |= IPV6_VERSION; ip6->ip6_hlim = CARP_DFLTTL; ip6->ip6_nxt = IPPROTO_CARP; + bzero(&sa, sizeof(sa)); /* set the source address */ - ifa = carp_best_ifa(AF_INET6, sc->sc_carpdev); + sa.sa_family = AF_INET6; + ifa = ifaof_ifpforaddr(&sa, sc->sc_carpdev); if (ifa != NULL) { bcopy(IFA_IN6(ifa), &ip6->ip6_src, sizeof(struct in6_addr));
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201701200015.v0K0FBqA016412>