In pfkey_sendup() we call sorwakeup() which asserts for NET_LOCK(), so
we are already at IPL_SOFTNET.
pfkeyv2_send() is called via pfkey_output() which is also called with
the NET_LOCK() held.
Finally replace a comment above pfkeyv2_ipo_walk() by the corresponding
assert.
ok?
Index: net/pfkey.c
===================================================================
RCS file: /cvs/src/sys/net/pfkey.c,v
retrieving revision 1.33
diff -u -p -r1.33 pfkey.c
--- net/pfkey.c 29 Nov 2016 10:22:30 -0000 1.33
+++ net/pfkey.c 10 Jan 2017 09:29:59 -0000
@@ -136,7 +136,8 @@ int
pfkey_sendup(struct socket *socket, struct mbuf *packet, int more)
{
struct mbuf *packet2;
- int s;
+
+ splsoftassert(IPL_SOFTNET);
if (more) {
if (!(packet2 = m_dup_pkt(packet, 0, M_DONTWAIT)))
@@ -144,13 +145,10 @@ pfkey_sendup(struct socket *socket, stru
} else
packet2 = packet;
- s = splsoftnet();
if (!sbappendaddr(&socket->so_rcv, &pfkey_addr, packet2, NULL)) {
m_freem(packet2);
- splx(s);
return (ENOBUFS);
}
- splx(s);
sorwakeup(socket);
return (0);
Index: net/pfkeyv2.c
===================================================================
RCS file: /cvs/src/sys/net/pfkeyv2.c,v
retrieving revision 1.148
diff -u -p -r1.148 pfkeyv2.c
--- net/pfkeyv2.c 15 Sep 2016 02:00:18 -0000 1.148
+++ net/pfkeyv2.c 10 Jan 2017 09:29:41 -0000
@@ -783,7 +783,7 @@ int
pfkeyv2_send(struct socket *socket, void *message, int len)
{
int i, j, rval = 0, mode = PFKEYV2_SENDMESSAGE_BROADCAST;
- int delflag = 0, s;
+ int delflag = 0;
struct sockaddr_encap encapdst, encapnetmask;
struct ipsec_policy *ipo, *tmpipo;
struct ipsec_acquire *ipa;
@@ -807,6 +807,8 @@ pfkeyv2_send(struct socket *socket, void
u_int rdomain;
+ splsoftassert(IPL_SOFTNET);
+
/* Verify that we received this over a legitimate pfkeyv2 socket */
bzero(headers, sizeof(headers));
@@ -940,8 +942,6 @@ pfkeyv2_send(struct socket *socket, void
}
#endif /* IPSEC */
- s = splsoftnet();
-
/* Find TDB */
sa2 = gettdb(rdomain, ssa->sadb_sa_spi, sunionp,
SADB_X_GETSPROTO(smsg->sadb_msg_satype));
@@ -949,7 +949,7 @@ pfkeyv2_send(struct socket *socket, void
/* If there's no such SA, we're done */
if (sa2 == NULL) {
rval = ESRCH;
- goto splxret;
+ goto ret;
}
/* If this is a reserved SA */
@@ -969,7 +969,7 @@ pfkeyv2_send(struct socket *socket, void
&newsa->tdb_sproto, &alg))) {
tdb_free(freeme);
freeme = NULL;
- goto splxret;
+ goto ret;
}
/* Initialize SA */
@@ -1020,7 +1020,7 @@ pfkeyv2_send(struct socket *socket, void
rval = EINVAL;
tdb_free(freeme);
freeme = NULL;
- goto splxret;
+ goto ret;
}
newsa->tdb_cur_allocations = sa2->tdb_cur_allocations;
@@ -1041,7 +1041,7 @@ pfkeyv2_send(struct socket *socket, void
headers[SADB_EXT_IDENTITY_DST] ||
headers[SADB_EXT_SENSITIVITY]) {
rval = EINVAL;
- goto splxret;
+ goto ret;
}
import_sa(sa2, headers[SADB_EXT_SA], NULL);
@@ -1059,7 +1059,6 @@ pfkeyv2_send(struct socket *socket, void
#endif
}
- splx(s);
break;
case SADB_ADD:
ssa = (struct sadb_sa *) headers[SADB_EXT_SA];
@@ -1092,21 +1091,19 @@ pfkeyv2_send(struct socket *socket, void
}
#endif /* IPSEC */
- s = splsoftnet();
-
sa2 = gettdb(rdomain, ssa->sadb_sa_spi, sunionp,
SADB_X_GETSPROTO(smsg->sadb_msg_satype));
/* We can't add an existing SA! */
if (sa2 != NULL) {
rval = EEXIST;
- goto splxret;
+ goto ret;
}
/* We can only add "mature" SAs */
if (ssa->sadb_sa_state != SADB_SASTATE_MATURE) {
rval = EINVAL;
- goto splxret;
+ goto ret;
}
/* Allocate and initialize new TDB */
@@ -1124,7 +1121,7 @@ pfkeyv2_send(struct socket *socket, void
&newsa->tdb_sproto, &alg))) {
tdb_free(freeme);
freeme = NULL;
- goto splxret;
+ goto ret;
}
import_sa(newsa, headers[SADB_EXT_SA], &ii);
@@ -1177,15 +1174,13 @@ pfkeyv2_send(struct socket *socket, void
rval = EINVAL;
tdb_free(freeme);
freeme = NULL;
- goto splxret;
+ goto ret;
}
}
/* Add TDB in table */
puttdb((struct tdb *) freeme);
- splx(s);
-
freeme = NULL;
break;
@@ -1194,19 +1189,16 @@ pfkeyv2_send(struct socket *socket, void
sunionp =
(union sockaddr_union *)(headers[SADB_EXT_ADDRESS_DST] +
sizeof(struct sadb_address));
- s = splsoftnet();
sa2 = gettdb(rdomain, ssa->sadb_sa_spi, sunionp,
SADB_X_GETSPROTO(smsg->sadb_msg_satype));
if (sa2 == NULL) {
rval = ESRCH;
- goto splxret;
+ goto ret;
}
tdb_delete(sa2);
- splx(s);
-
sa2 = NULL;
break;
@@ -1230,21 +1222,17 @@ pfkeyv2_send(struct socket *socket, void
(union sockaddr_union *)(headers[SADB_EXT_ADDRESS_DST] +
sizeof(struct sadb_address));
- s = splsoftnet();
-
sa2 = gettdb(rdomain, ssa->sadb_sa_spi, sunionp,
SADB_X_GETSPROTO(smsg->sadb_msg_satype));
if (sa2 == NULL) {
rval = ESRCH;
- goto splxret;
+ goto ret;
}
rval = pfkeyv2_get(sa2, headers, &freeme, NULL);
if (rval)
mode = PFKEYV2_SENDMESSAGE_UNICAST;
- splx(s);
-
break;
case SADB_REGISTER:
@@ -1323,15 +1311,12 @@ pfkeyv2_send(struct socket *socket, void
switch (smsg->sadb_msg_satype) {
case SADB_SATYPE_UNSPEC:
- s = splsoftnet();
-
for (ipo = TAILQ_FIRST(&ipsec_policy_head);
ipo != NULL; ipo = tmpipo) {
tmpipo = TAILQ_NEXT(ipo, ipo_list);
if (ipo->ipo_rdomain == rdomain)
ipsec_delete_policy(ipo);
}
- splx(s);
/* FALLTHROUGH */
case SADB_SATYPE_AH:
case SADB_SATYPE_ESP:
@@ -1340,12 +1325,9 @@ pfkeyv2_send(struct socket *socket, void
#ifdef TCP_SIGNATURE
case SADB_X_SATYPE_TCPSIGNATURE:
#endif /* TCP_SIGNATURE */
- s = splsoftnet();
-
tdb_walk(rdomain, pfkeyv2_flush_walker,
(u_int8_t *) &(smsg->sadb_msg_satype));
- splx(s);
break;
default:
@@ -1360,10 +1342,7 @@ pfkeyv2_send(struct socket *socket, void
dump_state.sadb_msg = (struct sadb_msg *) headers[0];
dump_state.socket = socket;
- s = splsoftnet();
rval = tdb_walk(rdomain, pfkeyv2_dump_walker, &dump_state);
- splx(s);
-
if (!rval)
goto realret;
@@ -1381,13 +1360,11 @@ pfkeyv2_send(struct socket *socket, void
sunionp = (union sockaddr_union *)
(headers[SADB_EXT_ADDRESS_DST] +
sizeof(struct sadb_address));
- s = splsoftnet();
-
tdb1 = gettdb(rdomain, ssa->sadb_sa_spi, sunionp,
SADB_X_GETSPROTO(smsg->sadb_msg_satype));
if (tdb1 == NULL) {
rval = ESRCH;
- goto splxret;
+ goto ret;
}
ssa = (struct sadb_sa *) headers[SADB_X_EXT_SA2];
@@ -1399,14 +1376,14 @@ pfkeyv2_send(struct socket *socket, void
SADB_X_GETSPROTO(sa_proto->sadb_protocol_proto));
if (tdb2 == NULL) {
rval = ESRCH;
- goto splxret;
+ goto ret;
}
/* Detect cycles */
for (tdb3 = tdb2; tdb3; tdb3 = tdb3->tdb_onext)
if (tdb3 == tdb1) {
rval = ESRCH;
- goto splxret;
+ goto ret;
}
/* Maintenance */
@@ -1421,8 +1398,6 @@ pfkeyv2_send(struct socket *socket, void
/* Link them */
tdb1->tdb_onext = tdb2;
tdb2->tdb_inext = tdb1;
-
- splx(s);
}
break;
@@ -1472,7 +1447,6 @@ pfkeyv2_send(struct socket *socket, void
headers[SADB_X_EXT_PROTOCOL],
headers[SADB_X_EXT_FLOW_TYPE]);
/* Determine whether the exact same SPD entry already exists. */
- s = splsoftnet();
if ((rn = rn_match(&encapdst, rnh)) != NULL) {
ipo = (struct ipsec_policy *)rn;
@@ -1494,7 +1468,6 @@ pfkeyv2_send(struct socket *socket, void
if (exists && (ipo->ipo_flags & IPSP_POLICY_STATIC)) {
if (!(sab->sadb_protocol_flags &
SADB_X_POLICYFLAGS_POLICY)) {
- splx(s);
goto ret;
}
}
@@ -1503,12 +1476,10 @@ pfkeyv2_send(struct socket *socket, void
if (delflag) {
if (exists) {
rval = ipsec_delete_policy(ipo);
- splx(s);
goto ret;
}
/* If we were asked to delete something non-existent,
error. */
- splx(s);
rval = ESRCH;
break;
}
@@ -1524,7 +1495,6 @@ pfkeyv2_send(struct socket *socket, void
/* Allocate policy entry */
ipo = pool_get(&ipsec_policy_pool, PR_NOWAIT|PR_ZERO);
if (ipo == NULL) {
- splx(s);
rval = ENOMEM;
goto ret;
}
@@ -1561,7 +1531,6 @@ pfkeyv2_send(struct socket *socket, void
else
ipsec_delete_policy(ipo);
- splx(s);
rval = EINVAL;
goto ret;
}
@@ -1596,7 +1565,6 @@ pfkeyv2_send(struct socket *socket, void
ipsec_delete_policy(ipo);
else
pool_put(&ipsec_policy_pool, ipo);
- splx(s);
rval = ENOBUFS;
goto ret;
}
@@ -1628,7 +1596,6 @@ pfkeyv2_send(struct socket *socket, void
ipsp_ids_free(ipo->ipo_ids);
pool_put(&ipsec_policy_pool, ipo);
- splx(s);
goto ret;
}
TAILQ_INSERT_HEAD(&ipsec_policy_head, ipo, ipo_list);
@@ -1636,8 +1603,6 @@ pfkeyv2_send(struct socket *socket, void
} else {
ipo->ipo_last_searched = ipo->ipo_flags = 0;
}
-
- splx(s);
}
break;
@@ -1678,7 +1643,6 @@ pfkeyv2_send(struct socket *socket, void
}
}
}
-
break;
@@ -1725,10 +1689,6 @@ realret:
free(sa1, M_PFKEY, 0);
return (rval);
-
-splxret:
- splx(s);
- goto ret;
}
/*
@@ -2187,15 +2147,14 @@ ret:
return (rval);
}
-/*
- * Caller is responsible for setting at least splsoftnet().
- */
int
pfkeyv2_ipo_walk(u_int rdomain, int (*walker)(struct ipsec_policy *, void *),
void *arg)
{
int rval = 0;
struct ipsec_policy *ipo;
+
+ splsoftassert(IPL_SOFTNET);
TAILQ_FOREACH(ipo, &ipsec_policy_head, ipo_list) {
if (ipo->ipo_rdomain != rdomain)