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 */

Reply via email to