git: 74f7e916211a - main - divert: Use CK_SLISTs for the divcb hash table
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 03 Dec 2025 14:43:34 UTC
The branch main has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=74f7e916211acafd10af05efd893ccbac1881119
commit 74f7e916211acafd10af05efd893ccbac1881119
Author: Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2025-12-03 13:43:04 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
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;