All code paths below are executed at IPL_SOFTNET, except the timeout that
I converted to timeout_set_proc(9) in order to grab the NET_LOCK().
ok?
Index: netinet/ip_ipsp.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_ipsp.c,v
retrieving revision 1.219
diff -u -p -r1.219 ip_ipsp.c
--- netinet/ip_ipsp.c 19 Dec 2016 08:36:49 -0000 1.219
+++ netinet/ip_ipsp.c 13 Feb 2017 10:49:53 -0000
@@ -176,7 +176,9 @@ reserve_spi(u_int rdomain, u_int32_t ssp
{
struct tdb *tdbp, *exists;
u_int32_t spi;
- int nums, s;
+ int nums;
+
+ splsoftassert(IPL_SOFTNET);
/* Don't accept ranges only encompassing reserved SPIs. */
if (sproto != IPPROTO_IPCOMP &&
@@ -229,10 +231,7 @@ reserve_spi(u_int rdomain, u_int32_t ssp
spi = htonl(spi);
/* Check whether we're using this SPI already. */
- s = splsoftnet();
exists = gettdb(rdomain, spi, dst, sproto);
- splx(s);
-
if (exists)
continue;
@@ -267,8 +266,6 @@ reserve_spi(u_int rdomain, u_int32_t ssp
* When we receive an IPSP packet, we need to look up its tunnel descriptor
* block, based on the SPI in the packet and the destination address (which
* is really one of our addresses if we received the packet!
- *
- * Caller is responsible for setting at least splsoftnet().
*/
struct tdb *
gettdb(u_int rdomain, u_int32_t spi, union sockaddr_union *dst, u_int8_t proto)
@@ -276,6 +273,8 @@ gettdb(u_int rdomain, u_int32_t spi, uni
u_int32_t hashval;
struct tdb *tdbp;
+ splsoftassert(IPL_SOFTNET);
+
if (tdbh == NULL)
return (struct tdb *) NULL;
@@ -469,15 +468,14 @@ tdb_hashstats(void)
}
#endif /* DDB */
-/*
- * Caller is responsible for setting at least splsoftnet().
- */
int
tdb_walk(u_int rdomain, int (*walker)(struct tdb *, void *, int), void *arg)
{
int i, rval = 0;
struct tdb *tdbp, *next;
+ splsoftassert(IPL_SOFTNET);
+
if (tdbh == NULL)
return ENOENT;
@@ -567,9 +565,6 @@ tdb_soft_firstuse(void *v)
NET_UNLOCK(s);
}
-/*
- * Caller is responsible for splsoftnet().
- */
void
tdb_rehash(void)
{
@@ -577,6 +572,8 @@ tdb_rehash(void)
u_int i, old_hashmask = tdb_hashmask;
u_int32_t hashval;
+ splsoftassert(IPL_SOFTNET);
+
tdb_hashmask = (tdb_hashmask << 1) | 1;
arc4random_buf(&tdbkey, sizeof(tdbkey));
@@ -633,7 +630,8 @@ void
puttdb(struct tdb *tdbp)
{
u_int32_t hashval;
- int s = splsoftnet();
+
+ splsoftassert(IPL_SOFTNET);
if (tdbh == NULL) {
arc4random_buf(&tdbkey, sizeof(tdbkey));
@@ -679,25 +677,19 @@ puttdb(struct tdb *tdbp)
tdb_count++;
ipsec_last_added = time_second;
-
- splx(s);
}
-/*
- * Caller is responsible to set at least splsoftnet().
- */
void
tdb_delete(struct tdb *tdbp)
{
struct tdb *tdbpp;
u_int32_t hashval;
- int s;
+
+ splsoftassert(IPL_SOFTNET);
if (tdbh == NULL)
return;
- s = splsoftnet();
-
hashval = tdb_hash(tdbp->tdb_rdomain, tdbp->tdb_spi,
&tdbp->tdb_dst, tdbp->tdb_sproto);
@@ -751,8 +743,6 @@ tdb_delete(struct tdb *tdbp)
tdbp->tdb_snext = NULL;
tdb_free(tdbp);
tdb_count--;
-
- splx(s);
}
/*
@@ -943,7 +933,7 @@ ipsp_ids_insert(struct ipsec_ids *ids)
}
ids->id_refcount = 1;
DPRINTF(("%s: new ids %p flow %u\n", __func__, ids, ids->id_flow));
- timeout_set(&ids->id_timeout, ipsp_ids_timeout, ids);
+ timeout_set_proc(&ids->id_timeout, ipsp_ids_timeout, ids);
return ids;
}
@@ -965,13 +955,14 @@ ipsp_ids_timeout(void *arg)
DPRINTF(("%s: ids %p count %d\n", __func__, ids, ids->id_refcount));
KASSERT(ids->id_refcount == 0);
- s = splsoftnet();
+
+ NET_LOCK(s);
RBT_REMOVE(ipsec_ids_tree, &ipsec_ids_tree, ids);
RBT_REMOVE(ipsec_ids_flows, &ipsec_ids_flows, ids);
free(ids->id_local, M_CREDENTIALS, 0);
free(ids->id_remote, M_CREDENTIALS, 0);
free(ids, M_CREDENTIALS, 0);
- splx(s);
+ NET_UNLOCK(s);
}
/* decrements refcount, actual free happens in timeout */