summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet/ip_carp.c33
1 files changed, 17 insertions, 16 deletions
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c
index 98561902d7b..e58d8b9793a 100644
--- a/sys/netinet/ip_carp.c
+++ b/sys/netinet/ip_carp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_carp.c,v 1.103 2005/03/13 18:26:29 pat Exp $ */
+/* $OpenBSD: ip_carp.c,v 1.104 2005/03/15 15:51:27 mcbride Exp $ */
/*
* Copyright (c) 2002 Michael Shalayeff. All rights reserved.
@@ -116,6 +116,7 @@ struct carp_softc {
int sc_flags_backup;
int sc_suppress;
+ int sc_bow_out;
int sc_sendad_errors;
#define CARP_SENDAD_MAX_ERRORS 3
@@ -369,10 +370,6 @@ carp_setroute(struct carp_softc *sc, int cmd)
}
break;
case RTM_DELETE:
- if (nr_ourif)
- rtrequest(RTM_DELETE, &sa,
- ifa->ifa_addr, ifa->ifa_netmask, 0,
- NULL);
break;
default:
break;
@@ -857,9 +854,9 @@ carp_send_ad(void *v)
goto retry_later;
}
- /* bow out if we've lost our UPness or RUNNINGuiness */
- if ((sc->sc_if.if_flags & (IFF_UP|IFF_RUNNING)) !=
- (IFF_UP|IFF_RUNNING)) {
+ /* bow out if we've gone to backup (the carp interface is going down) */
+ if (sc->sc_bow_out) {
+ sc->sc_bow_out = 0;
advbase = 255;
advskew = 255;
} else {
@@ -1324,13 +1321,13 @@ carp_setrun(struct carp_softc *sc, sa_family_t af)
switch (sc->sc_state) {
case INIT:
if (carp_opts[CARPCTL_PREEMPT] && !carp_suppress_preempt) {
+ carp_set_state(sc, MASTER);
+ carp_setroute(sc, RTM_ADD);
carp_send_ad(sc);
carp_send_arp(sc);
#ifdef INET6
carp_send_na(sc);
#endif /* INET6 */
- carp_set_state(sc, MASTER);
- carp_setroute(sc, RTM_ADD);
} else {
carp_set_state(sc, BACKUP);
carp_setroute(sc, RTM_DELETE);
@@ -1826,12 +1823,16 @@ carp_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr)
case SIOCSIFFLAGS:
if (sc->sc_state != INIT && !(ifr->ifr_flags & IFF_UP)) {
- sc->sc_if.if_flags &= ~IFF_UP;
timeout_del(&sc->sc_ad_tmo);
timeout_del(&sc->sc_md_tmo);
timeout_del(&sc->sc_md6_tmo);
- if (sc->sc_state == MASTER)
+ if (sc->sc_state == MASTER) {
+ /* we need the interface up to bow out */
+ sc->sc_if.if_flags |= IFF_UP;
+ sc->sc_bow_out = 1;
carp_send_ad(sc);
+ }
+ sc->sc_if.if_flags &= ~IFF_UP;
carp_set_state(sc, INIT);
carp_setrun(sc, 0);
} else if (sc->sc_state == INIT && (ifr->ifr_flags & IFF_UP)) {
@@ -1953,13 +1954,13 @@ int
carp_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
struct rtentry *rt)
{
- struct ifnet *ifp0 = ((struct carp_softc *)ifp->if_softc)->sc_carpdev;
+ struct carp_softc *sc = ((struct carp_softc *)ifp->if_softc);
- if (ifp0 != NULL)
- return (ifp0->if_output(ifp, m, sa, rt));
+ if (sc->sc_carpdev != NULL && sc->sc_state == MASTER)
+ return (sc->sc_carpdev->if_output(ifp, m, sa, rt));
else {
m_freem(m);
- return (EINVAL);
+ return (ENETUNREACH);
}
}