summaryrefslogtreecommitdiffstats
path: root/sys/netinet6
diff options
context:
space:
mode:
authorume <ume@FreeBSD.org>2005-08-17 16:46:55 +0000
committerume <ume@FreeBSD.org>2005-08-17 16:46:55 +0000
commitd73a48f4b83273aef6e3a84be7e569cb36b4eadf (patch)
tree1f6263bc3554b680be87affdc97b130dbe6725b9 /sys/netinet6
parentf8d92d59dbefcd27352b8440bbf9696247ef7b0c (diff)
downloadFreeBSD-src-d73a48f4b83273aef6e3a84be7e569cb36b4eadf.zip
FreeBSD-src-d73a48f4b83273aef6e3a84be7e569cb36b4eadf.tar.gz
- fix race condition using sx lock.
- use TAILQ_FOREACH() for readability. Suggested by: jhb
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/in6_src.c38
1 files changed, 24 insertions, 14 deletions
diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c
index b2ac0df..24534da 100644
--- a/sys/netinet6/in6_src.c
+++ b/sys/netinet6/in6_src.c
@@ -76,6 +76,7 @@
#include <sys/errno.h>
#include <sys/time.h>
#include <sys/kernel.h>
+#include <sys/sx.h>
#include <net/if.h>
#include <net/route.h>
@@ -100,6 +101,13 @@ static struct mtx addrsel_lock;
#define ADDRSEL_UNLOCK() mtx_unlock(&addrsel_lock)
#define ADDRSEL_LOCK_ASSERT() mtx_assert(&addrsel_lock, MA_OWNED)
+static struct sx addrsel_sxlock;
+#define ADDRSEL_SXLOCK_INIT() sx_init(&addrsel_sxlock, "addrsel_sxlock")
+#define ADDRSEL_SLOCK() sx_slock(&addrsel_sxlock)
+#define ADDRSEL_SUNLOCK() sx_sunlock(&addrsel_sxlock)
+#define ADDRSEL_XLOCK() sx_xlock(&addrsel_sxlock)
+#define ADDRSEL_XUNLOCK() sx_xunlock(&addrsel_sxlock)
+
#define ADDR_LABEL_NOTAPP (-1)
struct in6_addrpolicy defaultaddrpolicy;
@@ -837,6 +845,7 @@ void
addrsel_policy_init()
{
ADDRSEL_LOCK_INIT();
+ ADDRSEL_SXLOCK_INIT();
init_policy_queue();
@@ -953,16 +962,17 @@ add_addrsel_policyent(newpolicy)
MALLOC(new, struct addrsel_policyent *, sizeof(*new), M_IFADDR,
M_WAITOK);
+ ADDRSEL_XLOCK();
ADDRSEL_LOCK();
/* duplication check */
- for (pol = TAILQ_FIRST(&addrsel_policytab); pol;
- pol = TAILQ_NEXT(pol, ape_entry)) {
+ TAILQ_FOREACH(pol, &addrsel_policytab, ape_entry) {
if (SA6_ARE_ADDR_EQUAL(&newpolicy->addr,
&pol->ape_policy.addr) &&
SA6_ARE_ADDR_EQUAL(&newpolicy->addrmask,
&pol->ape_policy.addrmask)) {
ADDRSEL_UNLOCK();
+ ADDRSEL_XUNLOCK();
FREE(new, M_IFADDR);
return (EEXIST); /* or override it? */
}
@@ -975,6 +985,7 @@ add_addrsel_policyent(newpolicy)
TAILQ_INSERT_TAIL(&addrsel_policytab, new, ape_entry);
ADDRSEL_UNLOCK();
+ ADDRSEL_XUNLOCK();
return (0);
}
@@ -985,11 +996,11 @@ delete_addrsel_policyent(key)
{
struct addrsel_policyent *pol;
+ ADDRSEL_XLOCK();
ADDRSEL_LOCK();
/* search for the entry in the table */
- for (pol = TAILQ_FIRST(&addrsel_policytab); pol;
- pol = TAILQ_NEXT(pol, ape_entry)) {
+ TAILQ_FOREACH(pol, &addrsel_policytab, ape_entry) {
if (SA6_ARE_ADDR_EQUAL(&key->addr, &pol->ape_policy.addr) &&
SA6_ARE_ADDR_EQUAL(&key->addrmask,
&pol->ape_policy.addrmask)) {
@@ -998,11 +1009,13 @@ delete_addrsel_policyent(key)
}
if (pol == NULL) {
ADDRSEL_UNLOCK();
+ ADDRSEL_XUNLOCK();
return (ESRCH);
}
TAILQ_REMOVE(&addrsel_policytab, pol, ape_entry);
ADDRSEL_UNLOCK();
+ ADDRSEL_XUNLOCK();
return (0);
}
@@ -1015,16 +1028,14 @@ walk_addrsel_policy(callback, w)
struct addrsel_policyent *pol;
int error = 0;
- ADDRSEL_LOCK();
- for (pol = TAILQ_FIRST(&addrsel_policytab); pol;
- pol = TAILQ_NEXT(pol, ape_entry)) {
- ADDRSEL_UNLOCK();
- if ((error = (*callback)(&pol->ape_policy, w)) != 0)
+ ADDRSEL_SLOCK();
+ TAILQ_FOREACH(pol, &addrsel_policytab, ape_entry) {
+ if ((error = (*callback)(&pol->ape_policy, w)) != 0) {
+ ADDRSEL_SUNLOCK();
return (error);
- ADDRSEL_LOCK();
+ }
}
- ADDRSEL_UNLOCK();
-
+ ADDRSEL_SUNLOCK();
return (error);
}
@@ -1050,8 +1061,7 @@ match_addrsel_policy(key)
int matchlen, bestmatchlen = -1;
u_char *mp, *ep, *k, *p, m;
- for (pent = TAILQ_FIRST(&addrsel_policytab); pent;
- pent = TAILQ_NEXT(pent, ape_entry)) {
+ TAILQ_FOREACH(pent, &addrsel_policytab, ape_entry) {
matchlen = 0;
pol = &pent->ape_policy;
OpenPOWER on IntegriCloud