And use this mutex(9) to make the `session' dereference safe.
Hrvoje Popovski pointed me, he triggered netlock assertion with pipex(4)
pppoe sessions:
>
> r420-1# splassert: pipex_ppp_output: want 2 have 0
> Starting stack trace...
> pipex_ppp_output(fffffd80cb7c9500,ffff800022761200,21) at
> pipex_ppp_output+0x5e
> pppac_qstart(ffff800000e80ab0) at pppac_qstart+0x96
> ifq_serialize(ffff800000e80ab0,ffff800000e80b90) at ifq_serialize+0xfd
> taskq_thread(ffff800000030080) at taskq_thread+0x100
> end trace frame: 0x0, count: 253
> End of stack trace.
> splassert: pipex_ppp_output: want 2 have 0
> Starting stack trace...
> pipex_ppp_output(fffffd80c53b2300,ffff800022761200,21) at
> pipex_ppp_output+0x5e
> pppac_qstart(ffff800000e80ab0) at pppac_qstart+0x96
> ifq_serialize(ffff800000e80ab0,ffff800000e80b90) at ifq_serialize+0xfd
> taskq_thread(ffff800000030080) at taskq_thread+0x100
> end trace frame: 0x0, count: 253
> End of stack trace.
>
>
> r420-1# npppctl ses bri
> Ppp Id Assigned IPv4 Username Proto Tunnel From
> ---------- --------------- -------------------- -----
> -------------------------
> 7 10.53.251.22 r6202 L2TP 192.168.100.12:1701
> 1 10.53.253.11 hrvojepppoe11 PPPoE 90:e2:ba:33:af:ec
> 0 10.53.253.12 hrvojepppoe12 PPPoE ec:f4:bb:da:f7:f8
This means the hack we use to enforce pppac_qstart() and
pppx_if_qstart() be called with netlock held doesn't work anymore for
pppoe sessions:
/* XXXSMP: be sure pppac_qstart() called with NET_LOCK held */
ifq_set_maxlen(&ifp->if_snd, 1);
pptp and l2tp sessions are not affected, because the pcb layer is still
accessed with exclusive netlock held, but the code is common for all
session types. This mean we can't rely on netlock and should rework
pipex(4) locking.
The diff below introduces `pipex_list_mtx' mutex(9) to protect global
pipex(4) lists and made `session' dereference safe. It doesn't fix the
assertion, but only makes us sure the pppoe session can't be killed
concurrently while stack processes it.
I'll protect pipex(4) session data and rework pipex(4) output with next
diffs.
ok?
Index: sys/net/if_ethersubr.c
===================================================================
RCS file: /cvs/src/sys/net/if_ethersubr.c,v
retrieving revision 1.279
diff -u -p -r1.279 if_ethersubr.c
--- sys/net/if_ethersubr.c 22 Apr 2022 12:10:57 -0000 1.279
+++ sys/net/if_ethersubr.c 20 Jun 2022 14:44:03 -0000
@@ -545,11 +545,14 @@ ether_input(struct ifnet *ifp, struct mb
if (pipex_enable) {
struct pipex_session *session;
+ mtx_enter(&pipex_list_mtx);
if ((session = pipex_pppoe_lookup_session(m)) != NULL) {
pipex_pppoe_input(m, session);
+ mtx_leave(&pipex_list_mtx);
KERNEL_UNLOCK();
return;
}
+ mtx_leave(&pipex_list_mtx);
}
#endif
if (etype == ETHERTYPE_PPPOEDISC)
Index: sys/net/if_gre.c
===================================================================
RCS file: /cvs/src/sys/net/if_gre.c,v
retrieving revision 1.171
diff -u -p -r1.171 if_gre.c
--- sys/net/if_gre.c 10 Mar 2021 10:21:47 -0000 1.171
+++ sys/net/if_gre.c 20 Jun 2022 14:44:03 -0000
@@ -973,10 +973,18 @@ gre_input_1(struct gre_tunnel *key, stru
if (pipex_enable) {
struct pipex_session *session;
+ mtx_enter(&pipex_list_mtx);
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);
+ mtx_leave(&pipex_list_mtx);
+
+ if (m0 == NULL)
+ return (NULL);
+ }
+ mtx_leave(&pipex_list_mtx);
}
#endif
break;
Index: sys/net/if_pppx.c
===================================================================
RCS file: /cvs/src/sys/net/if_pppx.c,v
retrieving revision 1.114
diff -u -p -r1.114 if_pppx.c
--- sys/net/if_pppx.c 22 Feb 2022 01:15:02 -0000 1.114
+++ sys/net/if_pppx.c 20 Jun 2022 14:44:03 -0000
@@ -1322,9 +1322,7 @@ pppacclose(dev_t dev, int flags, int mod
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,11 +1382,15 @@ pppac_del_session(struct pppac_softc *sc
{
struct pipex_session *session;
+ mtx_enter(&pipex_list_mtx);
session = pipex_lookup_by_session_id(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);
+ mtx_leave(&pipex_list_mtx);
pipex_rele_session(session);
return (0);
@@ -1458,11 +1460,13 @@ pppac_qstart(struct ifqueue *ifq)
else
goto bad;
} else {
+ mtx_enter(&pipex_list_mtx);
session = pipex_lookup_by_ip_address(ip.ip_dst);
if (session != NULL) {
pipex_ip_output(m, session);
m = NULL;
}
+ mtx_leave(&pipex_list_mtx);
}
break;
}
Index: sys/net/pipex.c
===================================================================
RCS file: /cvs/src/sys/net/pipex.c,v
retrieving revision 1.136
diff -u -p -r1.136 pipex.c
--- sys/net/pipex.c 2 Jan 2022 22:36:04 -0000 1.136
+++ sys/net/pipex.c 20 Jun 2022 14:44:03 -0000
@@ -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->is_pppx == 0);
- pipex_unlink_session(session);
+ pipex_unlink_session_locked(session);
pipex_rele_session(session);
}
}
+
+ mtx_leave(&pipex_list_mtx);
}
int
@@ -375,8 +381,9 @@ pipex_link_session(struct pipex_session
{
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,
@@ -389,8 +396,10 @@ pipex_link_session(struct pipex_session
panic("rn_inithead() failed on pipex_link_session()");
}
if (pipex_lookup_by_session_id(session->protocol,
- session->session_id))
- return (EEXIST);
+ session->session_id)) {
+ error = EEXIST;
+ goto out;
+ }
session->ownersc = ownersc;
session->ifindex = ifp->if_index;
@@ -400,12 +409,16 @@ pipex_link_session(struct pipex_session
if (session->is_pppx == 0 &&
!in_nullhost(session->ip_address.sin_addr)) {
if (pipex_lookup_by_ip_address(session->ip_address.sin_addr)
- != NULL)
- return (EADDRINUSE);
+ != 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 +439,21 @@ pipex_link_session(struct pipex_session
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->is_pppx == 0 &&
@@ -466,10 +483,19 @@ pipex_unlink_session(struct pipex_sessio
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,34 +525,54 @@ Static int
pipex_config_session(struct pipex_session_config_req *req, void *ownersc)
{
struct pipex_session *session;
+ int error = 0;
NET_ASSERT_LOCKED();
+ mtx_enter(&pipex_list_mtx);
+
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 (session == NULL) {
+ error = EINVAL;
+ goto out;
+ }
+ if (session->ownersc != ownersc) {
+ error = EINVAL;
+ goto out;
+ }
session->ip_forward = req->pcr_ip_forward;
- return (0);
+out:
+ mtx_leave(&pipex_list_mtx);
+
+ 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();
+ mtx_enter(&pipex_list_mtx);
+
session = pipex_lookup_by_session_id(req->psr_protocol,
req->psr_session_id);
- if (session == NULL)
- return (EINVAL);
- if (session->ownersc != ownersc)
- return (EINVAL);
+ if (session == NULL) {
+ error = EINVAL;
+ goto out;
+ }
+ if (session->ownersc != ownersc) {
+ error = EINVAL;
+ goto out;
+ }
pipex_export_session_stats(session, &req->psr_stat);
- return (0);
+out:
+ mtx_leave(&pipex_list_mtx);
+
+ return error;
}
Static int
@@ -534,8 +580,10 @@ pipex_get_closed(struct pipex_session_li
{
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)
@@ -550,6 +598,8 @@ pipex_get_closed(struct pipex_session_li
}
}
+ mtx_leave(&pipex_list_mtx);
+
return (0);
}
@@ -559,6 +609,8 @@ pipex_lookup_by_ip_address(struct in_add
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));
@@ -592,7 +644,8 @@ pipex_lookup_by_session_id(int protocol,
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 &&
@@ -633,7 +686,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) {
@@ -656,7 +709,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->is_pppx == 0,
"FIXME session must not be released when pppx");
pipex_rele_session(session);
@@ -667,7 +720,7 @@ pipex_timer(void *ignored_arg)
}
}
- NET_UNLOCK();
+ mtx_leave(&pipex_list_mtx);
}
/***********************************************************************
@@ -1113,6 +1166,8 @@ pipex_pppoe_lookup_session(struct mbuf *
struct pipex_session *session;
struct pipex_pppoe_header pppoe;
+ MUTEX_ASSERT_LOCKED(&pipex_list_mtx);
+
/* short packet */
if (m0->m_pkthdr.len < (sizeof(struct ether_header) + sizeof(pppoe)))
return (NULL);
@@ -1139,7 +1194,8 @@ pipex_pppoe_input(struct mbuf *m0, struc
int hlen;
struct pipex_pppoe_header pppoe;
- NET_ASSERT_LOCKED();
+ MUTEX_ASSERT_LOCKED(&pipex_list_mtx);
+
/* already checked at pipex_pppoe_lookup_session */
KASSERT(m0->m_pkthdr.len >= (sizeof(struct ether_header) +
sizeof(pppoe)));
@@ -1302,6 +1358,8 @@ pipex_pptp_lookup_session(struct mbuf *m
uint16_t id;
int hlen;
+ MUTEX_ASSERT_LOCKED(&pipex_list_mtx);
+
if (m0->m_pkthdr.len < PIPEX_IPGRE_HDRLEN) {
PIPEX_DBG((NULL, LOG_DEBUG,
"<%s> packet length is too short", __func__));
@@ -1372,6 +1430,8 @@ pipex_pptp_input(struct mbuf *m0, struct
int rewind = 0;
NET_ASSERT_LOCKED();
+ MUTEX_ASSERT_LOCKED(&pipex_list_mtx);
+
KASSERT(m0->m_pkthdr.len >= PIPEX_IPGRE_HDRLEN);
pptp_session = &session->proto.pptp;
@@ -1535,6 +1595,8 @@ pipex_pptp_userland_lookup_session(struc
struct pipex_session *session;
uint16_t id, flags;
+ MUTEX_ASSERT_LOCKED(&pipex_list_mtx);
+
/* pullup */
if (m0->m_pkthdr.len < sizeof(gre)) {
PIPEX_DBG((NULL, LOG_DEBUG,
@@ -1592,6 +1654,8 @@ pipex_pptp_userland_output(struct mbuf *
u_char *cp, *cp0;
uint32_t val32;
+ MUTEX_ASSERT_LOCKED(&pipex_list_mtx);
+
len = sizeof(struct pipex_gre_header);
m_copydata(m0, 0, len, &gre0);
gre = &gre0;
@@ -1776,6 +1840,8 @@ pipex_l2tp_lookup_session(struct mbuf *m
uint16_t flags, session_id, ver;
u_char *cp, buf[PIPEX_L2TP_MINLEN];
+ MUTEX_ASSERT_LOCKED(&pipex_list_mtx);
+
if (m0->m_pkthdr.len < off + PIPEX_L2TP_MINLEN) {
PIPEX_DBG((NULL, LOG_DEBUG,
"<%s> packet length is too short", __func__));
@@ -1829,6 +1895,8 @@ pipex_l2tp_input(struct mbuf *m0, int of
int rewind = 0;
NET_ASSERT_LOCKED();
+ MUTEX_ASSERT_LOCKED(&pipex_list_mtx);
+
length = offset = ns = nr = 0;
l2tp_session = &session->proto.l2tp;
l2tp_session->ipsecflowinfo = ipsecflowinfo;
@@ -1975,6 +2043,8 @@ pipex_l2tp_userland_lookup_session(struc
struct pipex_session *session;
uint16_t session_id, tunnel_id, flags;
+ MUTEX_ASSERT_LOCKED(&pipex_list_mtx);
+
if (sa->sa_family != AF_INET && sa->sa_family != AF_INET6)
return (NULL);
@@ -2031,6 +2101,8 @@ pipex_l2tp_userland_output(struct mbuf *
struct pipex_l2tp_header *l2tp;
struct pipex_l2tp_seq_header *seq;
uint16_t ns, nr;
+
+ MUTEX_ASSERT_LOCKED(&pipex_list_mtx);
/* check length */
PIPEX_PULLUP(m0, sizeof(struct pipex_l2tp_header) +
Index: sys/net/pipex.h
===================================================================
RCS file: /cvs/src/sys/net/pipex.h,v
retrieving revision 1.31
diff -u -p -r1.31 pipex.h
--- sys/net/pipex.h 2 Jan 2022 22:36:04 -0000 1.31
+++ sys/net/pipex.h 20 Jun 2022 14:44:03 -0000
@@ -29,6 +29,8 @@
#ifndef NET_PIPEX_H
#define NET_PIPEX_H 1
+#include <sys/mutex.h>
+
/*
* Names for pipex sysctl objects
*/
@@ -174,6 +176,7 @@ struct pipex_session_descr_req {
#ifdef _KERNEL
extern int pipex_enable;
+extern struct mutex pipex_list_mtx;
struct pipex_session;
Index: sys/net/pipex_local.h
===================================================================
RCS file: /cvs/src/sys/net/pipex_local.h,v
retrieving revision 1.45
diff -u -p -r1.45 pipex_local.h
--- sys/net/pipex_local.h 15 Feb 2022 03:31:17 -0000 1.45
+++ sys/net/pipex_local.h 20 Jun 2022 14:44:03 -0000
@@ -26,6 +26,8 @@
* SUCH DAMAGE.
*/
+#include <sys/mutex.h>
+
#define PIPEX_PPTP 1
#define PIPEX_L2TP 1
#define PIPEX_PPPOE 1
@@ -53,10 +55,13 @@
* 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'
*/
+extern struct mutex pipex_list_mtx;
+
#ifdef PIPEX_MPPE
/* mppe rc4 key */
struct pipex_mppe {
@@ -152,24 +157,24 @@ 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 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 */
+ uint16_t 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 */
uint16_t ip_forward:1, /* [N] {en|dis}ableIP forwarding */
ip6_forward:1, /* [I] {en|dis}able IPv6 forwarding */
is_multicast:1, /* [I] virtual entry for multicast */
@@ -400,6 +405,7 @@ void pipex_rele_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 *,
Index: sys/netinet/ip_gre.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_gre.c,v
retrieving revision 1.73
diff -u -p -r1.73 ip_gre.c
--- sys/netinet/ip_gre.c 25 Feb 2022 23:51:03 -0000 1.73
+++ sys/netinet/ip_gre.c 20 Jun 2022 14:44:03 -0000
@@ -70,7 +70,6 @@ gre_usrreq(struct socket *so, int req, s
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,18 @@ gre_usrreq(struct socket *so, int req, s
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;
+
+ mtx_enter(&pipex_list_mtx);
+ session = pipex_pptp_userland_lookup_session_ipv4(m,
+ *ina_dst);
+
+ if(session != NULL)
+ m = pipex_pptp_userland_output(m, session);
+
+ mtx_leave(&pipex_list_mtx);
+ }
if (m == NULL)
return (ENOMEM);
Index: sys/netinet/udp_usrreq.c
===================================================================
RCS file: /cvs/src/sys/netinet/udp_usrreq.c,v
retrieving revision 1.278
diff -u -p -r1.278 udp_usrreq.c
--- sys/netinet/udp_usrreq.c 15 May 2022 09:12:20 -0000 1.278
+++ sys/netinet/udp_usrreq.c 20 Jun 2022 14:44:03 -0000
@@ -565,13 +565,17 @@ udp_input(struct mbuf **mp, int *offp, i
if (pipex_enable && inp->inp_pipex) {
struct pipex_session *session;
int off = iphlen + sizeof(struct udphdr);
+
+ mtx_enter(&pipex_list_mtx);
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 */
+ mtx_leave(&pipex_list_mtx);
return IPPROTO_DONE;
}
}
+ mtx_leave(&pipex_list_mtx);
}
#endif
@@ -1135,6 +1139,8 @@ udp_usrreq(struct socket *so, int req, s
if (inp->inp_pipex) {
struct pipex_session *session;
+ mtx_enter(&pipex_list_mtx);
+
if (addr != NULL)
session =
pipex_l2tp_userland_lookup_session(m,
@@ -1153,9 +1159,12 @@ udp_usrreq(struct socket *so, int req, s
if (session != NULL)
if ((m = pipex_l2tp_userland_output(
m, session)) == NULL) {
+ mtx_leave(&pipex_list_mtx);
error = ENOMEM;
goto release;
}
+
+ mtx_leave(&pipex_list_mtx);
}
#endif