summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/net/if_ethersubr.c4
-rw-r--r--sys/net/if_gre.c14
-rw-r--r--sys/net/if_pppx.c17
-rw-r--r--sys/net/pipex.c194
-rw-r--r--sys/net/pipex.h3
-rw-r--r--sys/net/pipex_local.h32
-rw-r--r--sys/netinet/ip_gre.c18
-rw-r--r--sys/netinet/udp_usrreq.c21
8 files changed, 222 insertions, 81 deletions
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
index 45dbd6c4d2d..b460036bc0e 100644
--- a/sys/net/if_ethersubr.c
+++ b/sys/net/if_ethersubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ethersubr.c,v 1.279 2022/04/22 12:10:57 bluhm Exp $ */
+/* $OpenBSD: if_ethersubr.c,v 1.280 2022/06/26 15:50:21 mvs Exp $ */
/* $NetBSD: if_ethersubr.c,v 1.19 1996/05/07 02:40:30 thorpej Exp $ */
/*
@@ -547,9 +547,11 @@ ether_input(struct ifnet *ifp, struct mbuf *m)
if ((session = pipex_pppoe_lookup_session(m)) != NULL) {
pipex_pppoe_input(m, session);
+ pipex_rele_session(session);
KERNEL_UNLOCK();
return;
}
+ pipex_rele_session(session);
}
#endif
if (etype == ETHERTYPE_PPPOEDISC)
diff --git a/sys/net/if_gre.c b/sys/net/if_gre.c
index d2f6524dd26..40441489b75 100644
--- a/sys/net/if_gre.c
+++ b/sys/net/if_gre.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_gre.c,v 1.171 2021/03/10 10:21:47 jsg Exp $ */
+/* $OpenBSD: if_gre.c,v 1.172 2022/06/26 15:50:21 mvs Exp $ */
/* $NetBSD: if_gre.c,v 1.9 1999/10/25 19:18:11 drochner Exp $ */
/*
@@ -974,9 +974,15 @@ gre_input_1(struct gre_tunnel *key, struct mbuf *m,
struct pipex_session *session;
session = pipex_pptp_lookup_session(m);
- if (session != NULL &&
- pipex_pptp_input(m, session) == NULL)
- return (NULL);
+ if (session != NULL) {
+ struct mbuf *m0;
+
+ m0 = pipex_pptp_input(m, session);
+ pipex_rele_session(session);
+
+ if (m0 == NULL)
+ return (NULL);
+ }
}
#endif
break;
diff --git a/sys/net/if_pppx.c b/sys/net/if_pppx.c
index 36aa942222c..0aaaedc038f 100644
--- a/sys/net/if_pppx.c
+++ b/sys/net/if_pppx.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_pppx.c,v 1.115 2022/06/26 13:14:37 mvs Exp $ */
+/* $OpenBSD: if_pppx.c,v 1.116 2022/06/26 15:50:21 mvs Exp $ */
/*
* Copyright (c) 2010 Claudio Jeker <claudio@openbsd.org>
@@ -1322,9 +1322,7 @@ pppacclose(dev_t dev, int flags, int mode, struct proc *p)
splx(s);
pool_put(&pipex_session_pool, sc->sc_multicast_session);
- NET_LOCK();
pipex_destroy_all_sessions(sc);
- NET_UNLOCK();
LIST_REMOVE(sc, sc_entry);
free(sc, M_DEVBUF, sizeof(*sc));
@@ -1384,13 +1382,19 @@ pppac_del_session(struct pppac_softc *sc, struct pipex_session_close_req *req)
{
struct pipex_session *session;
- session = pipex_lookup_by_session_id(req->pcr_protocol,
+ mtx_enter(&pipex_list_mtx);
+
+ session = pipex_lookup_by_session_id_locked(req->pcr_protocol,
req->pcr_session_id);
- if (session == NULL || session->ownersc != sc)
+ if (session == NULL || session->ownersc != sc) {
+ mtx_leave(&pipex_list_mtx);
return (EINVAL);
- pipex_unlink_session(session);
+ }
+ pipex_unlink_session_locked(session);
pipex_rele_session(session);
+ mtx_leave(&pipex_list_mtx);
+
return (0);
}
@@ -1461,6 +1465,7 @@ pppac_qstart(struct ifqueue *ifq)
session = pipex_lookup_by_ip_address(ip.ip_dst);
if (session != NULL) {
pipex_ip_output(m, session);
+ pipex_rele_session(session);
m = NULL;
}
}
diff --git a/sys/net/pipex.c b/sys/net/pipex.c
index 66737529b1b..cef23c856da 100644
--- a/sys/net/pipex.c
+++ b/sys/net/pipex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pipex.c,v 1.137 2022/06/26 13:14:37 mvs Exp $ */
+/* $OpenBSD: pipex.c,v 1.138 2022/06/26 15:50:21 mvs Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -40,6 +40,7 @@
#include <sys/kernel.h>
#include <sys/pool.h>
#include <sys/percpu.h>
+#include <sys/mutex.h>
#include <net/if.h>
#include <net/if_types.h>
@@ -79,6 +80,8 @@
#include <net/pipex.h>
#include "pipex_local.h"
+struct mutex pipex_list_mtx = MUTEX_INITIALIZER(IPL_SOFTNET);
+
struct pool pipex_session_pool;
struct pool mppe_key_pool;
@@ -88,17 +91,18 @@ struct pool mppe_key_pool;
* A atomic operation
* I immutable after creation
* N net lock
+ * L pipex_list_mtx
*/
int pipex_enable = 0; /* [N] */
struct pipex_hash_head
- pipex_session_list, /* [N] master session list */
- pipex_close_wait_list, /* [N] expired session list */
- pipex_peer_addr_hashtable[PIPEX_HASH_SIZE], /* [N] peer's address hash */
- pipex_id_hashtable[PIPEX_HASH_SIZE]; /* [N] peer id hash */
+ pipex_session_list, /* [L] master session list */
+ pipex_close_wait_list, /* [L] expired session list */
+ pipex_peer_addr_hashtable[PIPEX_HASH_SIZE], /* [L] peer's address hash */
+ pipex_id_hashtable[PIPEX_HASH_SIZE]; /* [L] peer id hash */
-struct radix_node_head *pipex_rd_head4 = NULL; /* [N] */
-struct radix_node_head *pipex_rd_head6 = NULL; /* [N] */
+struct radix_node_head *pipex_rd_head4 = NULL; /* [L] */
+struct radix_node_head *pipex_rd_head6 = NULL; /* [L] */
struct timeout pipex_timer_ch; /* callout timer context */
int pipex_prune = 1; /* [I] walk list every seconds */
@@ -145,16 +149,18 @@ pipex_destroy_all_sessions(void *ownersc)
{
struct pipex_session *session, *session_tmp;
- NET_ASSERT_LOCKED();
+ mtx_enter(&pipex_list_mtx);
LIST_FOREACH_SAFE(session, &pipex_session_list, session_list,
session_tmp) {
if (session->ownersc == ownersc) {
KASSERT((session->flags & PIPEX_SFLAGS_PPPX) == 0);
- pipex_unlink_session(session);
+ pipex_unlink_session_locked(session);
pipex_rele_session(session);
}
}
+
+ mtx_leave(&pipex_list_mtx);
}
int
@@ -263,6 +269,7 @@ pipex_init_session(struct pipex_session **rsession,
/* prepare a new session */
session = pool_get(&pipex_session_pool, PR_WAITOK | PR_ZERO);
+ refcnt_init(&session->pxs_refcnt);
mtx_init(&session->pxs_mtx, IPL_SOFTNET);
session->state = PIPEX_STATE_INITIAL;
session->protocol = req->pr_protocol;
@@ -363,6 +370,9 @@ pipex_init_session(struct pipex_session **rsession,
void
pipex_rele_session(struct pipex_session *session)
{
+ if (refcnt_rele(&session->pxs_refcnt) == 0)
+ return;
+
if (session->mppe_recv.old_session_keys)
pool_put(&mppe_key_pool, session->mppe_recv.old_session_keys);
counters_free(session->stat_counters, pxc_ncounters);
@@ -375,8 +385,9 @@ pipex_link_session(struct pipex_session *session, struct ifnet *ifp,
{
struct pipex_hash_head *chain;
struct radix_node *rn;
+ int error = 0;
- NET_ASSERT_LOCKED();
+ mtx_enter(&pipex_list_mtx);
if (pipex_rd_head4 == NULL) {
if (!rn_inithead((void **)&pipex_rd_head4,
@@ -388,9 +399,11 @@ pipex_link_session(struct pipex_session *session, struct ifnet *ifp,
offsetof(struct sockaddr_in6, sin6_addr)))
panic("rn_inithead() failed on pipex_link_session()");
}
- if (pipex_lookup_by_session_id(session->protocol,
- session->session_id))
- return (EEXIST);
+ if (pipex_lookup_by_session_id_locked(session->protocol,
+ session->session_id)) {
+ error = EEXIST;
+ goto out;
+ }
session->ownersc = ownersc;
session->ifindex = ifp->if_index;
@@ -399,13 +412,17 @@ pipex_link_session(struct pipex_session *session, struct ifnet *ifp,
if ((session->flags & PIPEX_SFLAGS_PPPX) == 0 &&
!in_nullhost(session->ip_address.sin_addr)) {
- if (pipex_lookup_by_ip_address(session->ip_address.sin_addr)
- != NULL)
- return (EADDRINUSE);
+ if (pipex_lookup_by_ip_address_locked(
+ session->ip_address.sin_addr) != NULL) {
+ error = EADDRINUSE;
+ goto out;
+ }
rn = rn_addroute(&session->ip_address, &session->ip_netmask,
pipex_rd_head4, session->ps4_rn, RTP_STATIC);
- if (rn == NULL)
- return (ENOMEM);
+ if (rn == NULL) {
+ error = ENOMEM;
+ goto out;
+ }
}
LIST_INSERT_HEAD(&pipex_session_list, session, session_list);
@@ -426,17 +443,21 @@ pipex_link_session(struct pipex_session *session, struct ifnet *ifp,
pipex_timer_start();
session->state = PIPEX_STATE_OPENED;
- return (0);
+out:
+ mtx_leave(&pipex_list_mtx);
+
+ return error;
}
void
-pipex_unlink_session(struct pipex_session *session)
+pipex_unlink_session_locked(struct pipex_session *session)
{
struct radix_node *rn;
+ MUTEX_ASSERT_LOCKED(&pipex_list_mtx);
+
session->ifindex = 0;
- NET_ASSERT_LOCKED();
if (session->state == PIPEX_STATE_CLOSED)
return;
if ((session->flags & PIPEX_SFLAGS_PPPX) == 0 &&
@@ -466,10 +487,19 @@ pipex_unlink_session(struct pipex_session *session)
pipex_timer_stop();
}
+void
+pipex_unlink_session(struct pipex_session *session)
+{
+ mtx_enter(&pipex_list_mtx);
+ pipex_unlink_session_locked(session);
+ mtx_leave(&pipex_list_mtx);
+}
+
int
pipex_notify_close_session(struct pipex_session *session)
{
- NET_ASSERT_LOCKED();
+ MUTEX_ASSERT_LOCKED(&pipex_list_mtx);
+
session->state = PIPEX_STATE_CLOSE_WAIT;
session->idle_time = 0;
LIST_INSERT_HEAD(&pipex_close_wait_list, session, state_list);
@@ -499,38 +529,49 @@ Static int
pipex_config_session(struct pipex_session_config_req *req, void *ownersc)
{
struct pipex_session *session;
+ int error = 0;
NET_ASSERT_LOCKED();
+
session = pipex_lookup_by_session_id(req->pcr_protocol,
req->pcr_session_id);
if (session == NULL)
return (EINVAL);
- if (session->ownersc != ownersc)
- return (EINVAL);
- if (req->pcr_ip_forward != 0)
- session->flags |= PIPEX_SFLAGS_IP_FORWARD;
- else
- session->flags &= ~PIPEX_SFLAGS_IP_FORWARD;
+ if (session->ownersc == ownersc) {
+ if (req->pcr_ip_forward != 0)
+ session->flags |= PIPEX_SFLAGS_IP_FORWARD;
+ else
+ session->flags &= ~PIPEX_SFLAGS_IP_FORWARD;
+ } else
+ error = EINVAL;
- return (0);
+ pipex_rele_session(session);
+
+ return error;
}
Static int
pipex_get_stat(struct pipex_session_stat_req *req, void *ownersc)
{
struct pipex_session *session;
+ int error = 0;
NET_ASSERT_LOCKED();
+
session = pipex_lookup_by_session_id(req->psr_protocol,
req->psr_session_id);
if (session == NULL)
return (EINVAL);
- if (session->ownersc != ownersc)
- return (EINVAL);
- pipex_export_session_stats(session, &req->psr_stat);
- return (0);
+ if (session->ownersc == ownersc)
+ pipex_export_session_stats(session, &req->psr_stat);
+ else
+ error = EINVAL;
+
+ pipex_rele_session(session);
+
+ return error;
}
Static int
@@ -538,8 +579,10 @@ pipex_get_closed(struct pipex_session_list_req *req, void *ownersc)
{
struct pipex_session *session, *session_tmp;
- NET_ASSERT_LOCKED();
bzero(req, sizeof(*req));
+
+ mtx_enter(&pipex_list_mtx);
+
LIST_FOREACH_SAFE(session, &pipex_close_wait_list, state_list,
session_tmp) {
if (session->ownersc != ownersc)
@@ -554,15 +597,19 @@ pipex_get_closed(struct pipex_session_list_req *req, void *ownersc)
}
}
+ mtx_leave(&pipex_list_mtx);
+
return (0);
}
Static struct pipex_session *
-pipex_lookup_by_ip_address(struct in_addr addr)
+pipex_lookup_by_ip_address_locked(struct in_addr addr)
{
struct pipex_session *session;
struct sockaddr_in pipex_in4, pipex_in4mask;
+ MUTEX_ASSERT_LOCKED(&pipex_list_mtx);
+
if (pipex_rd_head4 == NULL)
return (NULL);
bzero(&pipex_in4, sizeof(pipex_in4));
@@ -590,13 +637,31 @@ pipex_lookup_by_ip_address(struct in_addr addr)
return (session);
}
+struct pipex_session *
+pipex_lookup_by_ip_address(struct in_addr addr)
+{
+ struct pipex_session *session;
+
+ mtx_enter(&pipex_list_mtx);
+
+ session = pipex_lookup_by_ip_address_locked(addr);
+ if (session != NULL)
+ refcnt_take(&session->pxs_refcnt);
+
+ mtx_leave(&pipex_list_mtx);
+
+ return (session);
+}
+
+
Static struct pipex_session *
-pipex_lookup_by_session_id(int protocol, int session_id)
+pipex_lookup_by_session_id_locked(int protocol, int session_id)
{
struct pipex_hash_head *list;
struct pipex_session *session;
- NET_ASSERT_LOCKED();
+ MUTEX_ASSERT_LOCKED(&pipex_list_mtx);
+
list = PIPEX_ID_HASHTABLE(session_id);
LIST_FOREACH(session, list, id_chain) {
if (session->protocol == protocol &&
@@ -614,6 +679,22 @@ pipex_lookup_by_session_id(int protocol, int session_id)
return (session);
}
+struct pipex_session *
+pipex_lookup_by_session_id(int protocol, int session_id)
+{
+ struct pipex_session *session;
+
+ mtx_enter(&pipex_list_mtx);
+
+ session = pipex_lookup_by_session_id_locked(protocol, session_id);
+ if (session != NULL)
+ refcnt_take(&session->pxs_refcnt);
+
+ mtx_leave(&pipex_list_mtx);
+
+ return (session);
+}
+
/***********************************************************************
* Timer functions
***********************************************************************/
@@ -637,7 +718,7 @@ pipex_timer(void *ignored_arg)
timeout_add_sec(&pipex_timer_ch, pipex_prune);
- NET_LOCK();
+ mtx_enter(&pipex_list_mtx);
/* walk through */
LIST_FOREACH_SAFE(session, &pipex_session_list, session_list,
session_tmp) {
@@ -660,7 +741,7 @@ pipex_timer(void *ignored_arg)
if (session->idle_time < PIPEX_CLOSE_TIMEOUT)
continue;
/* Release the sessions when timeout */
- pipex_unlink_session(session);
+ pipex_unlink_session_locked(session);
KASSERTMSG((session->flags & PIPEX_SFLAGS_PPPX) == 0,
"FIXME session must not be released when pppx");
pipex_rele_session(session);
@@ -671,7 +752,7 @@ pipex_timer(void *ignored_arg)
}
}
- NET_UNLOCK();
+ mtx_leave(&pipex_list_mtx);
}
/***********************************************************************
@@ -695,9 +776,12 @@ pipex_ip_output(struct mbuf *m0, struct pipex_session *session)
m0 = ip_is_idle_packet(m0, &is_idle);
if (m0 == NULL)
goto dropped;
- if (is_idle == 0)
+ if (is_idle == 0) {
+ mtx_enter(&pipex_list_mtx);
/* update expire time */
session->idle_time = 0;
+ mtx_leave(&pipex_list_mtx);
+ }
}
/* adjust tcpmss */
@@ -914,9 +998,12 @@ pipex_ip_input(struct mbuf *m0, struct pipex_session *session)
m0 = ip_is_idle_packet(m0, &is_idle);
if (m0 == NULL)
goto drop;
- if (is_idle == 0)
+ if (is_idle == 0) {
/* update expire time */
+ mtx_enter(&pipex_list_mtx);
session->idle_time = 0;
+ mtx_leave(&pipex_list_mtx);
+ }
}
/* adjust tcpmss */
@@ -1132,8 +1219,11 @@ pipex_pppoe_lookup_session(struct mbuf *m0)
PIPEX_DBG((NULL, LOG_DEBUG, "<%s> session not found (id=%d)",
__func__, pppoe.session_id));
#endif
- if (session && session->proto.pppoe.over_ifidx != m0->m_pkthdr.ph_ifidx)
+ if (session && session->proto.pppoe.over_ifidx !=
+ m0->m_pkthdr.ph_ifidx) {
+ pipex_rele_session(session);
session = NULL;
+ }
return (session);
}
@@ -1144,7 +1234,6 @@ pipex_pppoe_input(struct mbuf *m0, struct pipex_session *session)
int hlen;
struct pipex_pppoe_header pppoe;
- NET_ASSERT_LOCKED();
/* already checked at pipex_pppoe_lookup_session */
KASSERT(m0->m_pkthdr.len >= (sizeof(struct ether_header) +
sizeof(pppoe)));
@@ -1568,6 +1657,8 @@ pipex_pptp_userland_lookup_session(struct mbuf *m0, struct sockaddr *sa)
/* lookup pipex session table */
id = ntohs(gre.call_id);
+ mtx_enter(&pipex_list_mtx);
+
list = PIPEX_PEER_ADDR_HASHTABLE(pipex_sockaddr_hash_key(sa));
LIST_FOREACH(session, list, peer_addr_chain) {
if (pipex_sockaddr_compar_addr(&session->peer.sa, sa) != 0)
@@ -1575,6 +1666,12 @@ pipex_pptp_userland_lookup_session(struct mbuf *m0, struct sockaddr *sa)
if (session->peer_session_id == id)
break;
}
+
+ if (session != NULL)
+ refcnt_take(&session->pxs_refcnt);
+
+ mtx_leave(&pipex_list_mtx);
+
#ifdef PIPEX_DEBUG
if (session == NULL) {
PIPEX_DBG((NULL, LOG_DEBUG,
@@ -1834,6 +1931,7 @@ pipex_l2tp_input(struct mbuf *m0, int off0, struct pipex_session *session,
int rewind = 0;
NET_ASSERT_LOCKED();
+
length = offset = ns = nr = 0;
l2tp_session = &session->proto.l2tp;
l2tp_session->ipsecflowinfo = ipsecflowinfo;
@@ -2010,6 +2108,8 @@ pipex_l2tp_userland_lookup_session(struct mbuf *m0, struct sockaddr *sa)
session_id = ntohs(l2tp.session_id);
tunnel_id = ntohs(l2tp.tunnel_id);
+ mtx_enter(&pipex_list_mtx);
+
list = PIPEX_PEER_ADDR_HASHTABLE(pipex_sockaddr_hash_key(sa));
LIST_FOREACH(session, list, peer_addr_chain) {
if (pipex_sockaddr_compar_addr(&session->peer.sa, sa) != 0)
@@ -2019,6 +2119,12 @@ pipex_l2tp_userland_lookup_session(struct mbuf *m0, struct sockaddr *sa)
if (session->peer_session_id == session_id)
break;
}
+
+ if (session != NULL)
+ refcnt_take(&session->pxs_refcnt);
+
+ mtx_leave(&pipex_list_mtx);
+
#ifdef PIPEX_DEBUG
if (session == NULL) {
PIPEX_DBG((NULL, LOG_DEBUG, "<%s> session not found "
diff --git a/sys/net/pipex.h b/sys/net/pipex.h
index a71f914826e..1f15f6bf8c9 100644
--- a/sys/net/pipex.h
+++ b/sys/net/pipex.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pipex.h,v 1.31 2022/01/02 22:36:04 jsg Exp $ */
+/* $OpenBSD: pipex.h,v 1.32 2022/06/26 15:50:21 mvs Exp $ */
/*
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -193,6 +193,7 @@ struct mbuf *pipex_l2tp_input (struct mbuf *, int off, struct pipex_se
struct pipex_session *pipex_l2tp_userland_lookup_session_ipv4 (struct mbuf *, struct in_addr);
struct pipex_session *pipex_l2tp_userland_lookup_session_ipv6 (struct mbuf *, struct in6_addr);
struct mbuf *pipex_l2tp_userland_output (struct mbuf *, struct pipex_session *);
+void pipex_rele_session(struct pipex_session *);
int pipex_ioctl (void *, u_long, caddr_t);
void pipex_session_init_mppe_recv(struct pipex_session *, int,
int, u_char *);
diff --git a/sys/net/pipex_local.h b/sys/net/pipex_local.h
index 7431f44487c..8959e21759d 100644
--- a/sys/net/pipex_local.h
+++ b/sys/net/pipex_local.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pipex_local.h,v 1.46 2022/06/26 13:14:37 mvs Exp $ */
+/* $OpenBSD: pipex_local.h,v 1.47 2022/06/26 15:50:21 mvs Exp $ */
/*
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -26,6 +26,11 @@
* SUCH DAMAGE.
*/
+#include <sys/mutex.h>
+#include <sys/refcnt.h>
+
+extern struct mutex pipex_list_mtx;
+
#define PIPEX_PPTP 1
#define PIPEX_L2TP 1
#define PIPEX_PPPOE 1
@@ -53,6 +58,7 @@
* Locks used to protect struct members:
* I immutable after creation
* N net lock
+ * L pipex_list_mtx
* s this pipex_session' `pxs_mtx'
* m this pipex_mppe' `pxm_mtx'
*/
@@ -153,26 +159,28 @@ struct cpumem;
/* pppac ip-extension session table */
struct pipex_session {
struct radix_node ps4_rn[2];
- /* [N] tree glue, and other values */
+ /* [L] tree glue, and other values */
struct radix_node ps6_rn[2];
- /* [N] tree glue, and other values */
+ /* [L] tree glue, and other values */
+
+ struct refcnt pxs_refcnt;
struct mutex pxs_mtx;
- LIST_ENTRY(pipex_session) session_list; /* [N] all session chain */
- LIST_ENTRY(pipex_session) state_list; /* [N] state list chain */
- LIST_ENTRY(pipex_session) id_chain; /* [N] id hash chain */
+ LIST_ENTRY(pipex_session) session_list; /* [L] all session chain */
+ LIST_ENTRY(pipex_session) state_list; /* [L] state list chain */
+ LIST_ENTRY(pipex_session) id_chain; /* [L] id hash chain */
LIST_ENTRY(pipex_session) peer_addr_chain;
- /* [N] peer's address hash chain */
- uint16_t state; /* [N] pipex session state */
+ /* [L] peer's address hash chain */
+ u_int state; /* [L] pipex session state */
#define PIPEX_STATE_INITIAL 0x0000
#define PIPEX_STATE_OPENED 0x0001
#define PIPEX_STATE_CLOSE_WAIT 0x0002
#define PIPEX_STATE_CLOSE_WAIT2 0x0003
#define PIPEX_STATE_CLOSED 0x0004
- uint32_t idle_time; /* [N] idle time in seconds */
+ uint32_t idle_time; /* [L] idle time in seconds */
- u_int flags; /* [N] flags, see below */
+ u_int flags; /* [N] flags, see below */
#define PIPEX_SFLAGS_IP_FORWARD 0x01 /* [N] enable IP forwarding */
#define PIPEX_SFLAGS_IP6_FORWARD 0x02 /* [N] enable IPv6 forwarding */
#define PIPEX_SFLAGS_MULTICAST 0x04 /* [I] virtual entry for
@@ -401,10 +409,10 @@ extern struct pool pipex_session_pool;
void pipex_destroy_all_sessions (void *);
int pipex_init_session(struct pipex_session **,
struct pipex_session_req *);
-void pipex_rele_session(struct pipex_session *);
int pipex_link_session(struct pipex_session *,
struct ifnet *, void *);
void pipex_unlink_session(struct pipex_session *);
+void pipex_unlink_session_locked(struct pipex_session *);
void pipex_export_session_stats(struct pipex_session *,
struct pipex_statistics *);
int pipex_config_session (struct pipex_session_config_req *,
@@ -413,7 +421,9 @@ int pipex_get_stat (struct pipex_session_stat_req *,
void *);
int pipex_get_closed (struct pipex_session_list_req *,
void *);
+struct pipex_session *pipex_lookup_by_ip_address_locked (struct in_addr);
struct pipex_session *pipex_lookup_by_ip_address (struct in_addr);
+struct pipex_session *pipex_lookup_by_session_id_locked (int, int);
struct pipex_session *pipex_lookup_by_session_id (int, int);
void pipex_ip_output (struct mbuf *, struct pipex_session *);
void pipex_ppp_output (struct mbuf *, struct pipex_session *, int);
diff --git a/sys/netinet/ip_gre.c b/sys/netinet/ip_gre.c
index eb68cb0b752..3e630221a18 100644
--- a/sys/netinet/ip_gre.c
+++ b/sys/netinet/ip_gre.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_gre.c,v 1.73 2022/02/25 23:51:03 guenther Exp $ */
+/* $OpenBSD: ip_gre.c,v 1.74 2022/06/26 15:50:21 mvs Exp $ */
/* $NetBSD: ip_gre.c,v 1.9 1999/10/25 19:18:11 drochner Exp $ */
/*
@@ -70,7 +70,6 @@ gre_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
if (inp != NULL && inp->inp_pipex && req == PRU_SEND) {
struct sockaddr_in *sin4;
struct in_addr *ina_dst;
- struct pipex_session *session;
ina_dst = NULL;
if ((so->so_state & SS_ISCONNECTED) != 0) {
@@ -81,10 +80,17 @@ gre_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
if (in_nam2sin(nam, &sin4) == 0)
ina_dst = &sin4->sin_addr;
}
- if (ina_dst != NULL &&
- (session = pipex_pptp_userland_lookup_session_ipv4(m,
- *ina_dst)))
- m = pipex_pptp_userland_output(m, session);
+ if (ina_dst != NULL) {
+ struct pipex_session *session;
+
+ session = pipex_pptp_userland_lookup_session_ipv4(m,
+ *ina_dst);
+
+ if(session != NULL) {
+ m = pipex_pptp_userland_output(m, session);
+ pipex_rele_session(session);
+ }
+ }
if (m == NULL)
return (ENOMEM);
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index 84592f9afb9..d0ef04a2b54 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: udp_usrreq.c,v 1.278 2022/05/15 09:12:20 dlg Exp $ */
+/* $OpenBSD: udp_usrreq.c,v 1.279 2022/06/26 15:50:21 mvs Exp $ */
/* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */
/*
@@ -565,12 +565,14 @@ udp_input(struct mbuf **mp, int *offp, int proto, int af)
if (pipex_enable && inp->inp_pipex) {
struct pipex_session *session;
int off = iphlen + sizeof(struct udphdr);
+
if ((session = pipex_l2tp_lookup_session(m, off)) != NULL) {
- if ((m = *mp = pipex_l2tp_input(m, off, session,
- ipsecflowinfo)) == NULL) {
- /* the packet is handled by PIPEX */
+ m = *mp = pipex_l2tp_input(m, off, session,
+ ipsecflowinfo);
+ pipex_rele_session(session);
+
+ if (m == NULL)
return IPPROTO_DONE;
- }
}
}
#endif
@@ -1150,12 +1152,15 @@ udp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *addr,
session =
pipex_l2tp_userland_lookup_session_ipv4(
m, inp->inp_faddr);
- if (session != NULL)
- if ((m = pipex_l2tp_userland_output(
- m, session)) == NULL) {
+ if (session != NULL) {
+ m = pipex_l2tp_userland_output(m, session);
+ pipex_rele_session(session);
+
+ if (m == NULL) {
error = ENOMEM;
goto release;
}
+ }
}
#endif