diff --git a/sys/netinet/ip_encap.c b/sys/netinet/ip_encap.c --- a/sys/netinet/ip_encap.c 2026-06-29 12:51:19.000000000 +0000 +++ b/sys/netinet/ip_encap.c 2026-07-19 07:47:01.904237148 +0000 @@ -90,8 +90,12 @@ #include #include #include +#include MALLOC_DEFINE(M_IPENCAP, "IP Encapsulation", "IP Encapsulation"); +/* DF-0689: serialize encaptab mutation vs. encap{4,6}_input walks. */ +static struct lwkt_token encaptab_token = LWKT_TOKEN_INITIALIZER(encaptab_token); + static void encap_add (struct encaptab *); static int mask_match (const struct encaptab *, const struct sockaddr *, const struct sockaddr *); @@ -171,6 +175,7 @@ match = NULL; matchprio = 0; + lwkt_gettoken(&encaptab_token); for (ep = LIST_FIRST(&encaptab); ep; ep = LIST_NEXT(ep, chain)) { if (ep->af != AF_INET) continue; @@ -224,8 +229,10 @@ } else { m_freem(m); } + lwkt_reltoken(&encaptab_token); return(IPPROTO_DONE); } + lwkt_reltoken(&encaptab_token); /* for backward compatibility */ if (proto == IPPROTO_IPV4 && ipip_input) { @@ -265,6 +272,7 @@ match = NULL; matchprio = 0; + lwkt_gettoken(&encaptab_token); for (ep = LIST_FIRST(&encaptab); ep; ep = LIST_NEXT(ep, chain)) { if (ep->af != AF_INET6) continue; @@ -291,16 +299,20 @@ } if (match) { + int rc; /* found a match */ psw = match->psw; if (psw && psw->pr_input) { encap_fillarg(m, match); - return (*psw->pr_input)(mp, offp, proto); + rc = (*psw->pr_input)(mp, offp, proto); } else { m_freem(m); - return IPPROTO_DONE; + rc = IPPROTO_DONE; } + lwkt_reltoken(&encaptab_token); + return rc; } + lwkt_reltoken(&encaptab_token); /* last resort: inject to raw socket */ return rip6_input(mp, offp, proto); @@ -326,7 +338,7 @@ { struct encaptab *ep; - crit_enter(); + lwkt_gettoken(&encaptab_token); /* sanity check on args */ if (sp->sa_len > sizeof ep->src || dp->sa_len > sizeof ep->dst) goto fail; @@ -368,11 +380,11 @@ encap_add(ep); - crit_exit(); + lwkt_reltoken(&encaptab_token); return ep; fail: - crit_exit(); + lwkt_reltoken(&encaptab_token); return NULL; } @@ -383,7 +395,7 @@ { struct encaptab *ep; - crit_enter(); + lwkt_gettoken(&encaptab_token); /* sanity check on args */ if (!func) goto fail; @@ -400,11 +412,11 @@ encap_add(ep); - crit_exit(); + lwkt_reltoken(&encaptab_token); return ep; fail: - crit_exit(); + lwkt_reltoken(&encaptab_token); return NULL; }