summaryrefslogtreecommitdiff
path: root/sys/netinet/ip_carp.c
diff options
context:
space:
mode:
authorRyan Thomas McBride <mcbride@cvs.openbsd.org>2003-11-04 21:30:45 +0000
committerRyan Thomas McBride <mcbride@cvs.openbsd.org>2003-11-04 21:30:45 +0000
commit81dab3d72aec5ca7f1ab6f8fed0d5683a5a5a986 (patch)
treedb9452af7c8e2d880c8a08c0c9b6154a4a8a1cf6 /sys/netinet/ip_carp.c
parent18dbb3dddbbf4b3f96032198b1119331543cf37a (diff)
Add carp_setroute(), add and remove routes when the carp(4) interface
enters and leaves MASTER state. Allows the system to connect to the common address when it is master. ok cedric@ henning@
Diffstat (limited to 'sys/netinet/ip_carp.c')
-rw-r--r--sys/netinet/ip_carp.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c
index 0cf3cc4a12c..dc66b9a8b68 100644
--- a/sys/netinet/ip_carp.c
+++ b/sys/netinet/ip_carp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_carp.c,v 1.20 2003/11/04 18:10:41 mcbride Exp $ */
+/* $OpenBSD: ip_carp.c,v 1.21 2003/11/04 21:30:44 mcbride Exp $ */
/*
* Copyright (c) 2002 Michael Shalayeff. All rights reserved.
@@ -146,6 +146,7 @@ void carp_hmac_generate(struct carp_softc *, u_int32_t *,
unsigned char *);
int carp_hmac_verify(struct carp_softc *, u_int32_t *,
unsigned char *);
+void carp_setroute(struct carp_softc *, int);
void carp_input_c(struct mbuf *, struct carp_softc *,
struct carp_header *, sa_family_t);
void carpattach(int);
@@ -244,6 +245,20 @@ carp_hmac_verify(struct carp_softc *sc, u_int32_t counter[2],
return (bcmp(md, md2, sizeof(md2)));
}
+void
+carp_setroute(struct carp_softc *sc, int cmd)
+{
+ struct ifaddr *ifa;
+ int s;
+
+ s = splnet();
+ TAILQ_FOREACH(ifa, &sc->sc_ac.ac_if.if_addrlist, ifa_list) {
+ if (ifa->ifa_addr->sa_family == AF_INET)
+ rtinit(ifa, cmd, RTF_UP | RTF_HOST);
+ }
+ splx(s);
+}
+
/*
* process input packet.
* we have rearranged checks order compared to the rfc,
@@ -467,6 +482,7 @@ carp_input_c(struct mbuf *m, struct carp_softc *sc,
timeout_del(&sc->sc_ad_tmo);
sc->sc_state = BACKUP;
carp_setrun(sc, 0);
+ carp_setroute(sc, RTM_DELETE);
}
break;
case BACKUP:
@@ -975,6 +991,7 @@ carp_master_down(void *v)
carp_send_na(sc);
#endif /* INET6 */
carp_setrun(sc, 0);
+ carp_setroute(sc, RTM_ADD);
break;
}
}
@@ -994,6 +1011,7 @@ carp_setrun(struct carp_softc *sc, sa_family_t af)
sc->sc_ac.ac_if.if_flags |= IFF_RUNNING;
else {
sc->sc_ac.ac_if.if_flags &= ~IFF_RUNNING;
+ carp_setroute(sc, RTM_DELETE);
return;
}
@@ -1006,8 +1024,10 @@ carp_setrun(struct carp_softc *sc, sa_family_t af)
carp_send_na(sc);
#endif
sc->sc_state = MASTER;
+ carp_setroute(sc, RTM_ADD);
} else {
sc->sc_state = BACKUP;
+ carp_setroute(sc, RTM_DELETE);
#ifdef INET
TAILQ_FOREACH(ifa, &sc->sc_ac.ac_if.if_addrlist,
ifa_list) {
@@ -1409,6 +1429,8 @@ carp_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr)
#ifdef INET
case AF_INET:
sc->if_flags |= IFF_UP;
+ bcopy(ifa->ifa_addr, ifa->ifa_dstaddr,
+ sizeof(struct sockaddr));
error = carp_set_addr(sc, satosin(ifa->ifa_addr));
break;
#endif /* INET */
@@ -1429,6 +1451,8 @@ carp_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr)
#ifdef INET
case AF_INET:
sc->if_flags |= IFF_UP;
+ bcopy(ifa->ifa_addr, ifa->ifa_dstaddr,
+ sizeof(struct sockaddr));
error = carp_set_addr(sc, satosin(&ifra->ifra_addr));
break;
#endif /* INET */