diff options
author | Ryan Thomas McBride <mcbride@cvs.openbsd.org> | 2005-02-07 04:50:52 +0000 |
---|---|---|
committer | Ryan Thomas McBride <mcbride@cvs.openbsd.org> | 2005-02-07 04:50:52 +0000 |
commit | b0ba6d049476183217e8b9f4204be9056a968cea (patch) | |
tree | 3730819694148c9d16dac6f73878d7cdbbc22af2 /sys | |
parent | 5116a0da2ea102908994946a1d06870f24bef7fe (diff) |
Prevent carp from attaching to other carp interfaces, which the
ifp->if_flags & IFF_MULTICAST checks no longer protect against.
ok pascoe@ mpf@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/netinet/ip_carp.c | 60 |
1 files changed, 25 insertions, 35 deletions
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c index e94cf1bf4f8..6bea368997d 100644 --- a/sys/netinet/ip_carp.c +++ b/sys/netinet/ip_carp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_carp.c,v 1.96 2005/02/07 04:14:39 pascoe Exp $ */ +/* $OpenBSD: ip_carp.c,v 1.97 2005/02/07 04:50:51 mcbride Exp $ */ /* * Copyright (c) 2002 Michael Shalayeff. All rights reserved. @@ -1440,6 +1440,9 @@ carp_set_ifp(struct carp_softc *sc, struct ifnet *ifp) if ((ifp->if_flags & IFF_MULTICAST) == 0) return (EADDRNOTAVAIL); + if (ifp->if_type == IFT_CARP) + return (EINVAL); + if (ifp->if_carp == NULL) { MALLOC(ncif, struct carp_if *, sizeof(*cif), M_IFADDR, M_NOWAIT); @@ -1540,40 +1543,6 @@ void carp_addr_updated(void *v) { struct carp_softc *sc = (struct carp_softc *) v; - struct ifaddr *ifa; - int new_naddrs = 0, new_naddrs6 = 0; - - TAILQ_FOREACH(ifa, &sc->sc_if.if_addrlist, ifa_list) { - if (ifa->ifa_addr->sa_family == AF_INET) - new_naddrs++; - else if (ifa->ifa_addr->sa_family == AF_INET6) - new_naddrs6++; - } - - /* Handle a callback after SIOCDIFADDR */ - if (new_naddrs < sc->sc_naddrs || new_naddrs6 < sc->sc_naddrs6) { - struct in_addr mc_addr; - struct in_multi *inm; - - sc->sc_naddrs = new_naddrs; - sc->sc_naddrs6 = new_naddrs6; - - /* Re-establish multicast membership removed by in_control */ - mc_addr.s_addr = INADDR_CARP_GROUP; - IN_LOOKUP_MULTI(mc_addr, &sc->sc_if, inm); - if (inm == NULL) { - bzero(&sc->sc_imo, sizeof(sc->sc_imo)); - - if (sc->sc_carpdev != NULL && sc->sc_naddrs > 0) - carp_join_multicast(sc); - } - - if (sc->sc_naddrs == 0 && sc->sc_naddrs6 == 0) { - sc->sc_if.if_flags &= ~IFF_UP; - carp_set_state(sc, INIT); - } else - carp_hmac_prepare(sc); - } carp_setrun(sc, 0); } @@ -1601,6 +1570,7 @@ carp_set_addr(struct carp_softc *sc, struct sockaddr_in *sin) /* and, yeah, we need a multicast-capable iface too */ if (ia->ia_ifp != &sc->sc_if && + ia->ia_ifp->if_type != IFT_CARP && (ia->ia_ifp->if_flags & IFF_MULTICAST) && (sin->sin_addr.s_addr & ia->ia_subnetmask) == ia->ia_subnet) { @@ -1702,6 +1672,7 @@ carp_set_addr6(struct carp_softc *sc, struct sockaddr_in6 *sin6) } /* and, yeah, we need a multicast-capable iface too */ if (ia->ia_ifp != &sc->sc_if && + ia->ia_ifp->if_type != IFT_CARP && (ia->ia_ifp->if_flags & IFF_MULTICAST) && (i == 4)) { if (!ia_if) @@ -1848,6 +1819,25 @@ carp_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr) } break; + case SIOCDIFADDR: + sc->sc_if.if_flags &= ~IFF_UP; + switch (ifa->ifa_addr->sa_family) { +#ifdef INET + case AF_INET: + sc->sc_naddrs--; + break; +#endif /* INET */ +#ifdef INET6 + case AF_INET6: + sc->sc_naddrs6--; + break; +#endif /* INET6 */ + default: + error = EAFNOSUPPORT; + break; + } + break; + case SIOCSIFFLAGS: if (sc->sc_state != INIT && !(ifr->ifr_flags & IFF_UP)) { sc->sc_if.if_flags &= ~IFF_UP; |