From 953fade1239ddddd9e112d513bee0ab49319a407 Mon Sep 17 00:00:00 2001 From: Martin Pieuchot Date: Mon, 16 Oct 2017 08:22:26 +0000 Subject: Last changes before running IPsec w/o KERNEL_LOCK(). Put more NET_ASSERT_LOCK() and document which globals it protects. Add a mutex for pfkeyv2 globals. Convert ipsp_delete_acquire() to timeout_set_proc(). Tested by Hrvoje Popovski, ok bluhm@ visa@ --- sys/netinet/ip_spd.c | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) (limited to 'sys/netinet/ip_spd.c') diff --git a/sys/netinet/ip_spd.c b/sys/netinet/ip_spd.c index 5d8b3a7b19e..8a26e990b6c 100644 --- a/sys/netinet/ip_spd.c +++ b/sys/netinet/ip_spd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_spd.c,v 1.92 2017/04/06 14:25:18 dhill Exp $ */ +/* $OpenBSD: ip_spd.c,v 1.93 2017/10/16 08:22:25 mpi Exp $ */ /* * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu) * @@ -45,7 +45,8 @@ int ipsp_acquire_sa(struct ipsec_policy *, union sockaddr_union *, union sockaddr_union *, struct sockaddr_encap *, struct mbuf *); struct ipsec_acquire *ipsp_pending_acquire(struct ipsec_policy *, union sockaddr_union *); -void ipsp_delete_acquire(void *); +void ipsp_delete_acquire_timo(void *); +void ipsp_delete_acquire(struct ipsec_acquire *); #ifdef ENCDEBUG #define DPRINTF(x) if (encdebug) printf x @@ -56,16 +57,21 @@ void ipsp_delete_acquire(void *); struct pool ipsec_policy_pool; struct pool ipsec_acquire_pool; int ipsec_policy_pool_initialized = 0; -int ipsec_acquire_pool_initialized = 0; +/* Protected by the NET_LOCK(). */ +int ipsec_acquire_pool_initialized = 0; struct radix_node_head **spd_tables; unsigned int spd_table_max; +TAILQ_HEAD(ipsec_acquire_head, ipsec_acquire) ipsec_acquire_head = + TAILQ_HEAD_INITIALIZER(ipsec_acquire_head); struct radix_node_head * spd_table_get(unsigned int rtableid) { unsigned int rdomain; + NET_ASSERT_LOCKED(); + if (spd_tables == NULL) return (NULL); @@ -83,6 +89,8 @@ spd_table_add(unsigned int rtableid) unsigned int rdomain; void *p; + NET_ASSERT_LOCKED(); + rdomain = rtable_l2(rtableid); if (spd_tables == NULL || rdomain > spd_table_max) { if ((p = mallocarray(rdomain + 1, sizeof(*rnh), @@ -135,6 +143,8 @@ ipsp_spd_lookup(struct mbuf *m, int af, int hlen, int *error, int direction, int signore = 0, dignore = 0; u_int rdomain = rtable_l2(m->m_pkthdr.ph_rtableid); + NET_ASSERT_LOCKED(); + /* * If there are no flows in place, there's no point * continuing with the SPD lookup. @@ -587,6 +597,8 @@ ipsec_delete_policy(struct ipsec_policy *ipo) struct radix_node *rn = (struct radix_node *)ipo; int err = 0; + NET_ASSERT_LOCKED(); + if (--ipo->ipo_ref_count > 0) return 0; @@ -614,13 +626,23 @@ ipsec_delete_policy(struct ipsec_policy *ipo) return err; } +void +ipsp_delete_acquire_timo(void *v) +{ + struct ipsec_acquire *ipa = v; + + NET_LOCK(); + ipsp_delete_acquire(ipa); + NET_UNLOCK(); +} + /* * Delete a pending IPsec acquire record. */ void -ipsp_delete_acquire(void *v) +ipsp_delete_acquire(struct ipsec_acquire *ipa) { - struct ipsec_acquire *ipa = v; + NET_ASSERT_LOCKED(); timeout_del(&ipa->ipa_timeout); TAILQ_REMOVE(&ipsec_acquire_head, ipa, ipa_next); @@ -639,6 +661,8 @@ ipsp_pending_acquire(struct ipsec_policy *ipo, union sockaddr_union *gw) { struct ipsec_acquire *ipa; + NET_ASSERT_LOCKED(); + TAILQ_FOREACH (ipa, &ipo->ipo_acquires, ipa_ipo_next) { if (!memcmp(gw, &ipa->ipa_addr, gw->sa.sa_len)) return ipa; @@ -657,6 +681,8 @@ ipsp_acquire_sa(struct ipsec_policy *ipo, union sockaddr_union *gw, { struct ipsec_acquire *ipa; + NET_ASSERT_LOCKED(); + /* Check whether request has been made already. */ if ((ipa = ipsp_pending_acquire(ipo, gw)) != NULL) return 0; @@ -674,7 +700,7 @@ ipsp_acquire_sa(struct ipsec_policy *ipo, union sockaddr_union *gw, ipa->ipa_addr = *gw; - timeout_set(&ipa->ipa_timeout, ipsp_delete_acquire, ipa); + timeout_set_proc(&ipa->ipa_timeout, ipsp_delete_acquire_timo, ipa); ipa->ipa_info.sen_len = ipa->ipa_mask.sen_len = SENT_LEN; ipa->ipa_info.sen_family = ipa->ipa_mask.sen_family = PF_KEY; -- cgit v1.2.3