From nobody Fri Aug 28 13:58:08 2026 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4hWg2S55vlz6qSFj for ; Fri, 28 Aug 2026 13:58:08 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR2" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hWg2S2pmRz3TqD for ; Fri, 28 Aug 2026 13:58:08 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1787925488; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=oXVf5FBHhQADg5ns8mqjGgNOWjM7RrZGCx9OjaJ2BCc=; b=FGsPFXoBJXGCQqE3fknCNfsKlWQzUYUFbGMyFkp9+tmxaiGvM8qIApJEFUXzBJslHPaoMK T+8lccDmmWvrls3IqdqTCcqkQPqbfB8dQ81Lg/DDCMkc0mXJV3s+scuBQkFs3QLk2xU5xf eKuXrePz+4L4rsJujmomk9lI9KqetfSca4xyPu27hwl84hOsuIAChxgvvSl4JUuraRgrmw LO8bgIMMTD0mh2yvqLhIqJJpfISpoBquzhrwWE70oAtsXZm0akKjOJz5oC0R6cg9SYR/6H n2pjpu38V+/vLu6KyqUbrgK3liruQB7b5pj/fBpb7m/vbqZ+b9JVTM0xjLHdsg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1787925488; a=rsa-sha256; cv=none; b=sMqdaMJKMKhBbyh+NZ3LwNEE9B9CiCKTfT6nE/d1DDtQjTFgrbdCBatRt/ObIW4AHGBqzP D5AZLGd0lC+EmYLUbTtCNoaB9E0G1CQNKkueOwTB6sqebWePws6w0LrL0nP3fHO9taCFwR Po8B3sXYOpvQSswcOyeM+XhodnbwgwyvVVAUt5ox4zb2GciXpBztBEk2wFxi6i7h43nJPN t8bDRGM6CiaEXreDxJWoni2UxTI4Jrb5v0iLJyuMyvSkuOSWFL2WL+ykLIsIEe6UJELhnV qmCgJWQe46SYu6woPpn+4krgOBkcTmAuDYmBZGsl/3oIdnBI1rxfVjl5C8mKEA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1787925488; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=oXVf5FBHhQADg5ns8mqjGgNOWjM7RrZGCx9OjaJ2BCc=; b=pKRVQ4bjU/bV8WWWrG0LzJwdHRbVfhex/ULZLpsKFnbRC8cyRZg3UfVNW2KByY3048Cxo+ KMiI4yIwN5NxqaIzMI7Iss6Hoz3OHYmTJkb/2HMvEZIY7BbT8bjNrH04lavNWFzloDzXK2 eenOLZOYIBHdPNEaSZ263JeN0POhDFuA1nc6nlE6CdbzO5dTiUlGr1pSdBJGXka6SCqp5J fCtm3KUwrZhxy38e8TCx+Wihz6lAHKJW7OjO6TW69Nf4kceENmJMIdFKezuQIf2gJRWu/6 fbEG6q4NYrZ6enEtRsZ54GPsyGziDN4jVDN02M3tl2JjsJ7scH8EuFM8QoXPQw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hWg2S18Hbz1BQx for ; Fri, 28 Aug 2026 13:58:08 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 37865 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Fri, 28 Aug 2026 13:58:08 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Bojan Novk=?utf-8?Q?ovi=C4=87?= Subject: git: bf05236727cf - main - pf: Send syncookies from the receiving thread List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: bnovkov X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: bf05236727cf367ee8e22ef47febebb319db9ddb Auto-Submitted: auto-generated Date: Fri, 28 Aug 2026 13:58:08 +0000 Message-Id: <6a9193f0.37865.1e1b1fd6@gitrepo.freebsd.org> The branch main has been updated by bnovkov: URL: https://cgit.FreeBSD.org/src/commit/?id=bf05236727cf367ee8e22ef47febebb319db9ddb commit bf05236727cf367ee8e22ef47febebb319db9ddb Author: Bojan Novković AuthorDate: 2026-08-17 14:10:36 +0000 Commit: Bojan Novković CommitDate: 2026-08-28 13:56:26 +0000 pf: Send syncookies from the receiving thread pf sends outbound packets by offloading them to a single per-vnet SWI handler through the `V_pf_sendqueue` mbuf queue. A large DDoS attack may overwhelm that per-vnet queue with syncookie packets and cause contention in the SWI handler that negatively affects other pf operations. Fix this by sending the initial syncookie challenge from the context of the receiving thread. This avoids the syncookie-induced contention on the `pf_intr` mbuf queue. Sponsored by: Klara, Inc. Sponsored by: Entersekt MFC after: 3 weeks Reviewed by: kp Differential Revision: https://reviews.freebsd.org/D59068 --- sys/netpfil/pf/pf.c | 67 ++++++++++++++++++++++++------------------ sys/netpfil/pf/pf.h | 9 +++++- sys/netpfil/pf/pf_syncookies.c | 32 ++++++++++++++++++-- 3 files changed, 76 insertions(+), 32 deletions(-) diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 92b441d1306a..54cf68cee50e 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -2690,6 +2690,43 @@ pf_icmp_mapping(struct pf_pdesc *pd, u_int8_t type, return (0); /* These types match to their own state */ } +#ifdef INET +void +pf_send_ip_direct(struct mbuf *m) +{ + if (pf_isforlocal(m, AF_INET)) { + KASSERT(m->m_pkthdr.rcvif == V_loif, + ("%s: rcvif != loif", __func__)); + + m->m_flags |= M_SKIP_FIREWALL; + m->m_pkthdr.csum_flags |= CSUM_IP_VALID | CSUM_IP_CHECKED | + CSUM_DATA_VALID | CSUM_PSEUDO_HDR; + m->m_pkthdr.csum_data = 0xffff; + ip_input(m); + } else { + ip_output(m, NULL, NULL, 0, NULL, NULL); + } +} +#endif + +#ifdef INET6 +void +pf_send_ip6_direct(struct mbuf *m) +{ + if (pf_isforlocal(m, AF_INET6)) { + KASSERT(m->m_pkthdr.rcvif == V_loif, + ("%s: rcvif != loif", __func__)); + + m->m_flags |= M_SKIP_FIREWALL | M_LOOP; + m->m_pkthdr.csum_flags |= CSUM_DATA_VALID | CSUM_PSEUDO_HDR; + m->m_pkthdr.csum_data = 0xffff; + ip6_input(m); + } else { + ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL); + } +} +#endif + void pf_intr(void *v) { @@ -2710,20 +2747,7 @@ pf_intr(void *v) switch (pfse->pfse_type) { #ifdef INET case PFSE_IP: { - if (pf_isforlocal(pfse->pfse_m, AF_INET)) { - KASSERT(pfse->pfse_m->m_pkthdr.rcvif == V_loif, - ("%s: rcvif != loif", __func__)); - - pfse->pfse_m->m_flags |= M_SKIP_FIREWALL; - pfse->pfse_m->m_pkthdr.csum_flags |= - CSUM_IP_VALID | CSUM_IP_CHECKED | - CSUM_DATA_VALID | CSUM_PSEUDO_HDR; - pfse->pfse_m->m_pkthdr.csum_data = 0xffff; - ip_input(pfse->pfse_m); - } else { - ip_output(pfse->pfse_m, NULL, NULL, 0, NULL, - NULL); - } + pf_send_ip_direct(pfse->pfse_m); break; } case PFSE_ICMP: @@ -2733,20 +2757,7 @@ pf_intr(void *v) #endif /* INET */ #ifdef INET6 case PFSE_IP6: - if (pf_isforlocal(pfse->pfse_m, AF_INET6)) { - KASSERT(pfse->pfse_m->m_pkthdr.rcvif == V_loif, - ("%s: rcvif != loif", __func__)); - - pfse->pfse_m->m_flags |= M_SKIP_FIREWALL | - M_LOOP; - pfse->pfse_m->m_pkthdr.csum_flags |= - CSUM_DATA_VALID | CSUM_PSEUDO_HDR; - pfse->pfse_m->m_pkthdr.csum_data = 0xffff; - ip6_input(pfse->pfse_m); - } else { - ip6_output(pfse->pfse_m, NULL, NULL, 0, NULL, - NULL, NULL); - } + pf_send_ip6_direct(pfse->pfse_m); break; case PFSE_ICMP6: icmp6_error(pfse->pfse_m, pfse->icmpopts.type, diff --git a/sys/netpfil/pf/pf.h b/sys/netpfil/pf/pf.h index 09bcd424db3e..6644499d9ce8 100644 --- a/sys/netpfil/pf/pf.h +++ b/sys/netpfil/pf/pf.h @@ -752,5 +752,12 @@ RB_PROTOTYPE(pf_anchor_global, pf_anchor, entry_global, pf_anchor_compare); RB_PROTOTYPE(pf_anchor_node, pf_anchor, entry_node, pf_anchor_compare); int pf_get_ruleset_number(u_int8_t); - +#ifdef _KERNEL +#ifdef INET +void pf_send_ip_direct(struct mbuf *m); +#endif +#ifdef INET6 +void pf_send_ip6_direct(struct mbuf *m); +#endif +#endif /* _KERNEL */ #endif /* _NET_PF_H_ */ diff --git a/sys/netpfil/pf/pf_syncookies.c b/sys/netpfil/pf/pf_syncookies.c index d11551ffb6ae..1a689b9e1df5 100644 --- a/sys/netpfil/pf/pf_syncookies.c +++ b/sys/netpfil/pf/pf_syncookies.c @@ -60,6 +60,9 @@ //#include "pflog.h" +#include "opt_inet.h" +#include "opt_inet6.h" + #include #include #include @@ -80,11 +83,16 @@ #include #include +#include #include #include +#include #include #include +#include +#include + #include #include @@ -291,13 +299,31 @@ pf_syncookie_send(struct pf_pdesc *pd, u_short *reason) { uint16_t mss; uint32_t iss; + struct mbuf *m; mss = max(V_tcp_mssdflt, pf_get_mss(pd)); iss = pf_syncookie_generate(pd, mss); - pf_send_tcp(NULL, pd->af, pd->dst, pd->src, *pd->dport, *pd->sport, - iss, ntohl(pd->hdr.tcp.th_seq) + 1, TH_SYN|TH_ACK, 0, mss, - 0, M_SKIP_FIREWALL | (pd->m->m_flags & M_LOOP), 0, 0, + + m = pf_build_tcp(NULL, pd->af, pd->dst, pd->src, *pd->dport, *pd->sport, + iss, ntohl(pd->hdr.tcp.th_seq) + 1, TH_SYN | TH_ACK, 0, mss, 0, + M_SKIP_FIREWALL | (pd->m->m_flags & M_LOOP), 0, 0, 0, pd->act.rtableid, reason); + if (m == NULL) + return; + switch (pd->af) { +#ifdef INET + case AF_INET: + pf_send_ip_direct(m); + break; +#endif /* INET */ +#ifdef INET6 + case AF_INET6: + pf_send_ip6_direct(m); + break; +#endif /* INET6 */ + default: + unhandled_af(pd->af); + } counter_u64_add(V_pf_status.lcounters[KLCNT_SYNCOOKIES_SENT], 1); /* XXX Maybe only in adaptive mode? */ atomic_add_64(&V_pf_status.syncookies_inflight[V_pf_syncookie_status.oddeven],