summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorRyan Thomas McBride <mcbride@cvs.openbsd.org>2005-02-07 04:50:52 +0000
committerRyan Thomas McBride <mcbride@cvs.openbsd.org>2005-02-07 04:50:52 +0000
commitb0ba6d049476183217e8b9f4204be9056a968cea (patch)
tree3730819694148c9d16dac6f73878d7cdbbc22af2 /sys
parent5116a0da2ea102908994946a1d06870f24bef7fe (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.c60
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;