From 6f5c556f471f5e2ef3c4b71c9c49bd7111fb84a1 Mon Sep 17 00:00:00 2001 From: mpi Date: Thu, 21 May 2015 09:17:53 +0000 Subject: [PATCH] Correctly state the link state to INVALID when creating a carp interface. Since vhe are allocated with M_ZERO and INIT is also defined to be 0, carp_set_state() would result in a no-op because of the state check. So explicitly initialize the state of a vhe to INIT and move the state check in carp_set_state_all() to prevent similar issues in the future. Problem and initial diff from Johan Ymerson, thanks! ok henning@ --- sys/netinet/ip_carp.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c index 76185eb4d10..310b0ce8ffc 100644 --- a/sys/netinet/ip_carp.c +++ b/sys/netinet/ip_carp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_carp.c,v 1.256 2015/05/15 11:53:06 claudio Exp $ */ +/* $OpenBSD: ip_carp.c,v 1.257 2015/05/21 09:17:53 mpi Exp $ */ /* * Copyright (c) 2002 Michael Shalayeff. All rights reserved. @@ -708,9 +708,7 @@ carpattach(int n) } int -carp_clone_create(ifc, unit) - struct if_clone *ifc; - int unit; +carp_clone_create(struct if_clone *ifc, int unit) { struct carp_softc *sc; struct ifnet *ifp; @@ -753,11 +751,11 @@ carp_clone_create(ifc, unit) ifp->if_sadl->sdl_type = IFT_CARP; ifp->if_output = carp_output; ifp->if_priority = IF_CARP_DEFAULT_PRIORITY; + ifp->if_link_state = LINK_STATE_INVALID; /* Hook carp_addr_updated to cope with address and route changes. */ sc->ah_cookie = hook_establish(sc->sc_if.if_addrhooks, 0, carp_addr_updated, sc); - carp_set_state_all(sc, INIT); return (0); } @@ -774,6 +772,7 @@ carp_new_vhost(struct carp_softc *sc, int vhid, int advskew) vhe->parent_sc = sc; vhe->vhid = vhid; vhe->advskew = advskew; + vhe->state = INIT; timeout_set(&vhe->ad_tmo, carp_send_ad, vhe); timeout_set(&vhe->md_tmo, carp_master_down, vhe); timeout_set(&vhe->md6_tmo, carp_master_down, vhe); @@ -2276,8 +2275,12 @@ carp_set_state_all(struct carp_softc *sc, int state) { struct carp_vhost_entry *vhe; - LIST_FOREACH(vhe, &sc->carp_vhosts, vhost_entries) + LIST_FOREACH(vhe, &sc->carp_vhosts, vhost_entries) { + if (vhe->state == state) + continue; + carp_set_state(vhe, state); + } } void @@ -2287,8 +2290,8 @@ carp_set_state(struct carp_vhost_entry *vhe, int state) static const char *carp_states[] = { CARP_STATES }; int loglevel; - if (vhe->state == state) - return; + KASSERT(vhe->state != state); + if (vhe->state == INIT || state == INIT) loglevel = LOG_WARNING; else -- 2.20.1