summaryrefslogtreecommitdiff
path: root/sys/netinet
diff options
context:
space:
mode:
authorGerhard Roth <gerhard@cvs.openbsd.org>2014-11-03 11:43:48 +0000
committerGerhard Roth <gerhard@cvs.openbsd.org>2014-11-03 11:43:48 +0000
commit3089de36809d2e94db55c6f961443484d21c1191 (patch)
treedca1cd731960b46008cdcd35dffc4466cefbd6d5 /sys/netinet
parent8f2950c2fe3854f987ec488c4304f62f71903750 (diff)
Fix kernel stack overflow by preventing carp_send_ad_all() from re-entrant
calls. Also, when adjusting demote counts, don't call carp_send_ad_all() for every ifgroup with a demote count of 1 but rather call it only once after adjusting the demote counts of all ifgroups. ok bluhm@ mpf@
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/ip_carp.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c
index 20678436cfe..d3ef05cae66 100644
--- a/sys/netinet/ip_carp.c
+++ b/sys/netinet/ip_carp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_carp.c,v 1.236 2014/10/07 08:47:28 mpi Exp $ */
+/* $OpenBSD: ip_carp.c,v 1.237 2014/11/03 11:43:47 gerhard Exp $ */
/*
* Copyright (c) 2002 Michael Shalayeff. All rights reserved.
@@ -170,6 +170,8 @@ struct carp_softc {
int carp_opts[CARPCTL_MAXID] = { 0, 1, 0, LOG_CRIT }; /* XXX for now */
struct carpstats carpstats;
+int carp_send_all_recur = 0;
+
struct carp_if {
TAILQ_HEAD(, carp_softc) vhif_vrs;
int vhif_nvrs;
@@ -925,6 +927,9 @@ carp_send_ad_all(void)
struct carp_if *cif;
struct carp_softc *vh;
+ if (carp_send_all_recur > 0)
+ return;
+ ++carp_send_all_recur;
TAILQ_FOREACH(ifp, &ifnet, if_list) {
if (ifp->if_carp == NULL || ifp->if_type == IFT_CARP)
continue;
@@ -937,6 +942,7 @@ carp_send_ad_all(void)
}
}
}
+ --carp_send_all_recur;
}
void
@@ -2424,7 +2430,7 @@ void
carp_group_demote_adj(struct ifnet *ifp, int adj, char *reason)
{
struct ifg_list *ifgl;
- int *dm;
+ int *dm, need_ad;
struct carp_softc *nil = NULL;
if (ifp->if_type == IFT_CARP) {
@@ -2435,6 +2441,7 @@ carp_group_demote_adj(struct ifnet *ifp, int adj, char *reason)
*dm = 0;
}
+ need_ad = 0;
TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) {
if (!strcmp(ifgl->ifgl_group->ifg_group, IFG_ALL))
continue;
@@ -2446,12 +2453,14 @@ carp_group_demote_adj(struct ifnet *ifp, int adj, char *reason)
*dm = 0;
if (adj > 0 && *dm == 1)
- carp_send_ad_all();
+ need_ad = 1;
CARP_LOG(LOG_ERR, nil,
("%s demoted group %s by %d to %d (%s)",
ifp->if_xname, ifgl->ifgl_group->ifg_group,
adj, *dm, reason));
}
+ if (need_ad)
+ carp_send_ad_all();
}
int