Please drop previous diff. counters_read(9) could sleep, so we can't
call it with mutex(9) held.

The diff below still uses `pipex_list_mtx' mutex(9) for pipex(4) lists
protection, but for safe `session' dereference it user reference
counters.

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      22 Jun 2022 11:41:05 -0000
@@ -547,9 +547,11 @@ ether_input(struct ifnet *ifp, struct mb
 
                        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)
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    22 Jun 2022 11:41:05 -0000
@@ -974,9 +974,15 @@ gre_input_1(struct gre_tunnel *key, stru
                        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;
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   22 Jun 2022 11:41:05 -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,13 +1382,19 @@ pppac_del_session(struct pppac_softc *sc
 {
        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;
                                }
                        }
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     22 Jun 2022 11:41:05 -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
@@ -263,6 +269,7 @@ pipex_init_session(struct pipex_session 
 
        /* prepare a new session */
        session = pool_get(&pipex_session_pool, PR_WAITOK | PR_ZERO);
+       refcnt_init(&session->pxs_refs);
        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 
 void
 pipex_rele_session(struct pipex_session *session)
 {
+       if (refcnt_rele(&session->pxs_refs) == 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 
 {
        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 
                    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 
 
        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);
+               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 
                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 +487,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 +529,46 @@ 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);
-       session->ip_forward = req->pcr_ip_forward;
 
-       return (0);
+       if (session->ownersc == ownersc)
+               session->ip_forward = req->pcr_ip_forward;
+       else
+               error = EINVAL;
+
+       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
@@ -534,8 +576,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,15 +594,19 @@ pipex_get_closed(struct pipex_session_li
                }
        }
 
+       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));
@@ -586,13 +634,31 @@ pipex_lookup_by_ip_address(struct in_add
        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_refs);
+
+       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 &&
@@ -610,6 +676,22 @@ pipex_lookup_by_session_id(int protocol,
        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_refs);
+
+       mtx_leave(&pipex_list_mtx);
+
+       return (session);
+}
+
 /***********************************************************************
  * Timer functions
  ***********************************************************************/
@@ -633,7 +715,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 +738,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 +749,7 @@ pipex_timer(void *ignored_arg)
                }
        }
 
-       NET_UNLOCK();
+       mtx_leave(&pipex_list_mtx);
 }
 
 /***********************************************************************
@@ -690,9 +772,12 @@ pipex_ip_output(struct mbuf *m0, struct 
                        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 */
@@ -909,9 +994,12 @@ pipex_ip_input(struct mbuf *m0, struct p
                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 */
@@ -1139,7 +1227,6 @@ pipex_pppoe_input(struct mbuf *m0, struc
        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)));
@@ -1563,6 +1650,8 @@ pipex_pptp_userland_lookup_session(struc
        /* 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)
@@ -1570,6 +1659,12 @@ pipex_pptp_userland_lookup_session(struc
                if (session->peer_session_id == id)
                        break;
        }
+
+       if (session != NULL)
+               refcnt_take(&session->pxs_refs);
+
+       mtx_leave(&pipex_list_mtx);
+
 #ifdef PIPEX_DEBUG
        if (session == NULL) {
                PIPEX_DBG((NULL, LOG_DEBUG,
@@ -1829,6 +1924,7 @@ pipex_l2tp_input(struct mbuf *m0, int of
        int rewind = 0;
 
        NET_ASSERT_LOCKED();
+
        length = offset = ns = nr = 0;
        l2tp_session = &session->proto.l2tp;
        l2tp_session->ipsecflowinfo = ipsecflowinfo;
@@ -2005,6 +2101,8 @@ pipex_l2tp_userland_lookup_session(struc
        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)
@@ -2014,6 +2112,12 @@ pipex_l2tp_userland_lookup_session(struc
                if (session->peer_session_id == session_id)
                        break;
        }
+
+       if (session != NULL)
+               refcnt_take(&session->pxs_refs);
+
+       mtx_leave(&pipex_list_mtx);
+
 #ifdef PIPEX_DEBUG
        if (session == NULL) {
                PIPEX_DBG((NULL, LOG_DEBUG, "<%s> session not found "
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     22 Jun 2022 11:41:06 -0000
@@ -193,6 +193,7 @@ struct mbuf           *pipex_l2tp_input 
 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 *);
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       22 Jun 2022 11:41:06 -0000
@@ -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'
  */
@@ -152,24 +158,26 @@ 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_refs;
        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 */
@@ -396,10 +404,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 *,
@@ -408,7 +416,9 @@ int                   pipex_get_stat (st
                           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);
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        22 Jun 2022 11:41:06 -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,17 @@ 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;
+
+                       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);
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    22 Jun 2022 11:41:06 -0000
@@ -565,12 +565,14 @@ udp_input(struct mbuf **mp, int *offp, i
        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, s
                                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
 

Reply via email to