The branch main has been updated by markj:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=74f7e916211acafd10af05efd893ccbac1881119

commit 74f7e916211acafd10af05efd893ccbac1881119
Author:     Mark Johnston <[email protected]>
AuthorDate: 2025-12-03 13:43:04 +0000
Commit:     Mark Johnston <[email protected]>
CommitDate: 2025-12-03 13:43:04 +0000

    divert: Use CK_SLISTs for the divcb hash table
    
    The hash table is accessed in ip_divert_packet(), and there the accesses
    are synchronized only by the net epoch, so plain SLIST is not safe.
    
    Reviewed by:    ae
    MFC after:      1 week
    Sponsored by:   OPNsense
    Sponsored by:   Klara, Inc.
    Differential Revision:  https://reviews.freebsd.org/D54011
---
 sys/netinet/ip_divert.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c
index a88497a71019..9f1d862a0531 100644
--- a/sys/netinet/ip_divert.c
+++ b/sys/netinet/ip_divert.c
@@ -34,6 +34,7 @@
 #include "opt_sctp.h"
 
 #include <sys/param.h>
+#include <sys/ck.h>
 #include <sys/eventhandler.h>
 #include <sys/kernel.h>
 #include <sys/lock.h>
@@ -136,7 +137,7 @@ static int div_output_outbound(int family, struct socket 
*so, struct mbuf *m);
 
 struct divcb {
        union {
-               SLIST_ENTRY(divcb)      dcb_next;
+               CK_SLIST_ENTRY(divcb)   dcb_next;
                intptr_t                dcb_bound;
 #define        DCB_UNBOUND     ((intptr_t)-1)
        };
@@ -146,7 +147,7 @@ struct divcb {
        struct epoch_context     dcb_epochctx;
 };
 
-SLIST_HEAD(divhashhead, divcb);
+CK_SLIST_HEAD(divhashhead, divcb);
 
 VNET_DEFINE_STATIC(struct divhashhead, divhash[DIVHASHSIZE]) = {};
 #define        V_divhash       VNET(divhash)
@@ -272,7 +273,7 @@ divert_packet(struct mbuf *m, bool incoming)
        }
 
        /* Put packet on socket queue, if any */
-       SLIST_FOREACH(dcb, &V_divhash[DIVHASH(nport)], dcb_next)
+       CK_SLIST_FOREACH(dcb, &V_divhash[DIVHASH(nport)], dcb_next)
                if (dcb->dcb_port == nport)
                        break;
 
@@ -600,7 +601,7 @@ div_detach(struct socket *so)
        so->so_pcb = NULL;
        DIVERT_LOCK();
        if (dcb->dcb_bound != DCB_UNBOUND)
-               SLIST_REMOVE(&V_divhash[DCBHASH(dcb)], dcb, divcb, dcb_next);
+               CK_SLIST_REMOVE(&V_divhash[DCBHASH(dcb)], dcb, divcb, dcb_next);
        V_dcb_count--;
        V_dcb_gencnt++;
        DIVERT_UNLOCK();
@@ -619,16 +620,16 @@ div_bind(struct socket *so, struct sockaddr *nam, struct 
thread *td)
                return EINVAL;
        port = ((struct sockaddr_in *)nam)->sin_port;
        DIVERT_LOCK();
-       SLIST_FOREACH(dcb, &V_divhash[DIVHASH(port)], dcb_next)
+       CK_SLIST_FOREACH(dcb, &V_divhash[DIVHASH(port)], dcb_next)
                if (dcb->dcb_port == port) {
                        DIVERT_UNLOCK();
                        return (EADDRINUSE);
                }
        dcb = so->so_pcb;
        if (dcb->dcb_bound != DCB_UNBOUND)
-               SLIST_REMOVE(&V_divhash[DCBHASH(dcb)], dcb, divcb, dcb_next);
+               CK_SLIST_REMOVE(&V_divhash[DCBHASH(dcb)], dcb, divcb, dcb_next);
        dcb->dcb_port = port;
-       SLIST_INSERT_HEAD(&V_divhash[DIVHASH(port)], dcb, dcb_next);
+       CK_SLIST_INSERT_HEAD(&V_divhash[DIVHASH(port)], dcb, dcb_next);
        DIVERT_UNLOCK();
 
        return (0);
@@ -667,7 +668,7 @@ div_pcblist(SYSCTL_HANDLER_ARGS)
 
        DIVERT_LOCK();
        for (int i = 0; i < DIVHASHSIZE; i++)
-               SLIST_FOREACH(dcb, &V_divhash[i], dcb_next) {
+               CK_SLIST_FOREACH(dcb, &V_divhash[i], dcb_next) {
                        if (dcb->dcb_gencnt <= xig.xig_gen) {
                                struct xinpcb xi;
 

Reply via email to