From nobody Wed Feb 12 19:39:07 2025 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 4YtTCJ1scMz5nGsM; Wed, 12 Feb 2025 19:39: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 "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4YtTCJ01F6z3Xc6; Wed, 12 Feb 2025 19:39:08 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1739389148; 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=6gwFGKWlhD2imUmWLr9p10sGN5V8Yh71CHsVev7CBwk=; b=R+6u5wXPsNJUFeVtg5gxh3avoEkGlJ2XTwSbGre43jwOBZyki7Dux5JvhfVVCSBAqwt9C8 n07ot1kIpwpkbmMPiW1R1kBX6RsJL3NgBOZOnoSdT9jnFgganb/1KWWOgmlHyM+4HX3Y2Y vxqxvPh9LkGSsTbEwSnCtIHWDjTLGupwVQhtkjRnPDOLw9JilNgIx3I4Zdd+GtHAnLMhQv yWjK4ClNQR0P87gSkcjgFgCwKIJCVSXQIQbysFquHJqyeHF6l4G1BWTX8i2LZ79tMBQmKy vau8IAc5VXVplMGbeGmf8s5Vlp8Q+RZHM1Qy5TG4sgAV/CJRS3lpa4qeuDVWjw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1739389148; 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=6gwFGKWlhD2imUmWLr9p10sGN5V8Yh71CHsVev7CBwk=; b=jndaiSBEErqVC/r9svy8m9vIwyAVJ8zd8fYh6rrzmtfnq+vcNGU4ckYj49Li+2lWjpkCWP oF5+r62BuXnsw0vjiU1UQAEcs2NmR1lWpPAlsI15Ztm6e70/VEyUIRFPhUHce0vOt0v+QC cW1Acjy/xzn6Ws1+v7+dByvFH9wqKekpa7Z1sJk762mLjki9vLVsfGsn9sCBtZ5m9OUuCv 73O5kmvFaE2OfJNg/mt9g/2y1TmY5c5ZP3cc0yNct3gUIZvU73sE/h6bFrWKe6CGEGhyQZ lq6iiAbTIlQrbdajMWp+3j7+HUearJtkKUEnKrREscO7ZaHcaqCWZqNAGsczWA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1739389148; a=rsa-sha256; cv=none; b=jyre6WqicA6As9KVi5w5//nL29NlrVWnoI+2gINWCpi65C3YFO0AnoqTASynCT16dy0SMR V77QxQp6tGgUJqDizNK0lhE7vG2RB9PFQLlcPPTZCkAakI30SRTgpULExlyfDhFtN5q2Bu F/MVbwbd8ECxkE9iKNsbQNCQ0vBn+l1fE6jTq722ZRBOFmiB/bjqHOjcjr8/dly8NTGO6Z wy2TwXrVLzqQ3RfMD5zEu0cOeAs/tSMFEFW5IagWqjAEY9WJRoYSYFLrjmJ4WhD6R5nE1o E6LODxLL0uLZdVg9NAElK99o7RztSs3TUEJ4gYlzOjLoQBhfN+bYXuuMwhNazA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (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 did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4YtTCH6TVmz1BFf; Wed, 12 Feb 2025 19:39:07 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 51CJd7fH061682; Wed, 12 Feb 2025 19:39:07 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 51CJd70e061679; Wed, 12 Feb 2025 19:39:07 GMT (envelope-from git) Date: Wed, 12 Feb 2025 19:39:07 GMT Message-Id: <202502121939.51CJd70e061679@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kristof Provost Subject: git: f3e8653badad - main - pf: fold pf_test_state_sctp into pf_test_state as well 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 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kp X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: f3e8653badad6989a570f959faa44bb0166d8f09 Auto-Submitted: auto-generated The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=f3e8653badad6989a570f959faa44bb0166d8f09 commit f3e8653badad6989a570f959faa44bb0166d8f09 Author: Kristof Provost AuthorDate: 2025-02-06 14:52:56 +0000 Commit: Kristof Provost CommitDate: 2025-02-12 19:38:38 +0000 pf: fold pf_test_state_sctp into pf_test_state as well Just like TCP and UDP we can fold the SCTP code into pf_test_state(). This does require a dummy variable to hold the protocol checksum, because unlike TCP and UDP the SCTP checksum is 32-bits. We don't need to change the checksum though, so simply pointing the pcksum pointer to a safe dummy location suffices to re-use pf_test_state(). Sponsored by: Rubicon Communications, LLC ("Netgate") --- sys/net/pfvar.h | 1 + sys/netpfil/pf/pf.c | 190 ++++++++++++++++++---------------------------------- 2 files changed, 65 insertions(+), 126 deletions(-) diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index d4c3831b49f8..88364aaa45ed 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -1662,6 +1662,7 @@ struct pf_pdesc { #define PFDESC_SCTP_ADD_IP 0x1000 u_int16_t sctp_flags; u_int32_t sctp_initiate_tag; + u_int16_t sctp_dummy_sum; struct pf_krule *related_rule; struct pf_sctp_multihome_jobs sctp_multihome_jobs; diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index c92faf43d967..3f9e5473deea 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -361,11 +361,11 @@ int pf_icmp_state_lookup(struct pf_state_key_cmp *, int, int *, int, int); static int pf_test_state_icmp(struct pf_kstate **, struct pf_pdesc *, u_short *); +static int pf_sctp_track(struct pf_kstate *, struct pf_pdesc *, + u_short *); static void pf_sctp_multihome_detach_addr(const struct pf_kstate *); static void pf_sctp_multihome_delayed(struct pf_pdesc *, struct pfi_kkif *, struct pf_kstate *, int); -static int pf_test_state_sctp(struct pf_kstate **, - struct pf_pdesc *, u_short *); static u_int16_t pf_calc_mss(struct pf_addr *, sa_family_t, int, u_int16_t); static int pf_check_proto_cksum(struct mbuf *, int, int, @@ -6977,6 +6977,61 @@ pf_test_state(struct pf_kstate **state, struct pf_pdesc *pd, u_short *reason) else (*state)->timeout = PFTM_UDP_SINGLE; break; + case IPPROTO_SCTP: + if ((src->state >= SCTP_SHUTDOWN_SENT || src->state == SCTP_CLOSED) && + (dst->state >= SCTP_SHUTDOWN_SENT || dst->state == SCTP_CLOSED) && + pd->sctp_flags & PFDESC_SCTP_INIT) { + pf_set_protostate(*state, PF_PEER_BOTH, SCTP_CLOSED); + pf_unlink_state(*state); + *state = NULL; + return (PF_DROP); + } + + if (pf_sctp_track(*state, pd, reason) != PF_PASS) + return (PF_DROP); + + /* Track state. */ + if (pd->sctp_flags & PFDESC_SCTP_INIT) { + if (src->state < SCTP_COOKIE_WAIT) { + pf_set_protostate(*state, psrc, SCTP_COOKIE_WAIT); + (*state)->timeout = PFTM_SCTP_OPENING; + } + } + if (pd->sctp_flags & PFDESC_SCTP_INIT_ACK) { + MPASS(dst->scrub != NULL); + if (dst->scrub->pfss_v_tag == 0) + dst->scrub->pfss_v_tag = pd->sctp_initiate_tag; + } + + /* + * Bind to the correct interface if we're if-bound. For multihomed + * extra associations we don't know which interface that will be until + * here, so we've inserted the state on V_pf_all. Fix that now. + */ + if ((*state)->kif == V_pfi_all && + (*state)->rule->rule_flag & PFRULE_IFBOUND) + (*state)->kif = pd->kif; + + if (pd->sctp_flags & (PFDESC_SCTP_COOKIE | PFDESC_SCTP_HEARTBEAT_ACK)) { + if (src->state < SCTP_ESTABLISHED) { + pf_set_protostate(*state, psrc, SCTP_ESTABLISHED); + (*state)->timeout = PFTM_SCTP_ESTABLISHED; + } + } + if (pd->sctp_flags & (PFDESC_SCTP_SHUTDOWN | + PFDESC_SCTP_SHUTDOWN_COMPLETE)) { + if (src->state < SCTP_SHUTDOWN_PENDING) { + pf_set_protostate(*state, psrc, SCTP_SHUTDOWN_PENDING); + (*state)->timeout = PFTM_SCTP_CLOSING; + } + } + if (pd->sctp_flags & (PFDESC_SCTP_SHUTDOWN_COMPLETE | PFDESC_SCTP_ABORT)) { + pf_set_protostate(*state, psrc, SCTP_CLOSED); + (*state)->timeout = PFTM_SCTP_CLOSED; + } + + (*state)->expire = pf_get_uptime(); + break; default: /* update states */ if (src->state < PFOTHERS_SINGLE) @@ -7064,129 +7119,6 @@ pf_sctp_track(struct pf_kstate *state, struct pf_pdesc *pd, return (PF_PASS); } -static int -pf_test_state_sctp(struct pf_kstate **state, struct pf_pdesc *pd, - u_short *reason) -{ - struct pf_state_key_cmp key; - struct pf_state_peer *src, *dst; - struct sctphdr *sh = &pd->hdr.sctp; - u_int8_t psrc; //, pdst; - - bzero(&key, sizeof(key)); - key.af = pd->af; - key.proto = IPPROTO_SCTP; - PF_ACPY(&key.addr[pd->sidx], pd->src, key.af); - PF_ACPY(&key.addr[pd->didx], pd->dst, key.af); - key.port[pd->sidx] = sh->src_port; - key.port[pd->didx] = sh->dest_port; - - STATE_LOOKUP(&key, *state, pd); - - if (pd->dir == (*state)->direction) { - src = &(*state)->src; - dst = &(*state)->dst; - psrc = PF_PEER_SRC; - } else { - src = &(*state)->dst; - dst = &(*state)->src; - psrc = PF_PEER_DST; - } - - if ((src->state >= SCTP_SHUTDOWN_SENT || src->state == SCTP_CLOSED) && - (dst->state >= SCTP_SHUTDOWN_SENT || dst->state == SCTP_CLOSED) && - pd->sctp_flags & PFDESC_SCTP_INIT) { - pf_set_protostate(*state, PF_PEER_BOTH, SCTP_CLOSED); - pf_unlink_state(*state); - *state = NULL; - return (PF_DROP); - } - - if (pf_sctp_track(*state, pd, reason) != PF_PASS) - return (PF_DROP); - - /* Track state. */ - if (pd->sctp_flags & PFDESC_SCTP_INIT) { - if (src->state < SCTP_COOKIE_WAIT) { - pf_set_protostate(*state, psrc, SCTP_COOKIE_WAIT); - (*state)->timeout = PFTM_SCTP_OPENING; - } - } - if (pd->sctp_flags & PFDESC_SCTP_INIT_ACK) { - MPASS(dst->scrub != NULL); - if (dst->scrub->pfss_v_tag == 0) - dst->scrub->pfss_v_tag = pd->sctp_initiate_tag; - } - - /* - * Bind to the correct interface if we're if-bound. For multihomed - * extra associations we don't know which interface that will be until - * here, so we've inserted the state on V_pf_all. Fix that now. - */ - if ((*state)->kif == V_pfi_all && - (*state)->rule->rule_flag & PFRULE_IFBOUND) - (*state)->kif = pd->kif; - - if (pd->sctp_flags & (PFDESC_SCTP_COOKIE | PFDESC_SCTP_HEARTBEAT_ACK)) { - if (src->state < SCTP_ESTABLISHED) { - pf_set_protostate(*state, psrc, SCTP_ESTABLISHED); - (*state)->timeout = PFTM_SCTP_ESTABLISHED; - } - } - if (pd->sctp_flags & (PFDESC_SCTP_SHUTDOWN | - PFDESC_SCTP_SHUTDOWN_COMPLETE)) { - if (src->state < SCTP_SHUTDOWN_PENDING) { - pf_set_protostate(*state, psrc, SCTP_SHUTDOWN_PENDING); - (*state)->timeout = PFTM_SCTP_CLOSING; - } - } - if (pd->sctp_flags & (PFDESC_SCTP_SHUTDOWN_COMPLETE | PFDESC_SCTP_ABORT)) { - pf_set_protostate(*state, psrc, SCTP_CLOSED); - (*state)->timeout = PFTM_SCTP_CLOSED; - } - - (*state)->expire = pf_get_uptime(); - - /* translate source/destination address, if necessary */ - if ((*state)->key[PF_SK_WIRE] != (*state)->key[PF_SK_STACK]) { - uint16_t checksum = 0; - struct pf_state_key *nk; - int afto, sidx, didx; - - if (PF_REVERSED_KEY((*state)->key, pd->af)) - nk = (*state)->key[pd->sidx]; - else - nk = (*state)->key[pd->didx]; - - afto = pd->af != nk->af; - sidx = afto ? pd->didx : pd->sidx; - didx = afto ? pd->sidx : pd->didx; - - if (afto || PF_ANEQ(pd->src, &nk->addr[sidx], pd->af) || - nk->port[sidx] != pd->hdr.sctp.src_port) { - pf_change_ap(pd->m, pd->src, &pd->hdr.sctp.src_port, - pd->ip_sum, &checksum, &nk->addr[sidx], - nk->port[sidx], 1, pd->af, pd->naf); - } - - if (afto || PF_ANEQ(pd->dst, &nk->addr[didx], pd->af) || - nk->port[didx] != pd->hdr.sctp.dest_port) { - pf_change_ap(pd->m, pd->dst, &pd->hdr.sctp.dest_port, - pd->ip_sum, &checksum, &nk->addr[didx], - nk->port[didx], 1, pd->af, pd->naf); - } - - if (afto) { - PF_ACPY(&pd->nsaddr, &nk->addr[sidx], nk->af); - PF_ACPY(&pd->ndaddr, &nk->addr[didx], nk->af); - pd->naf = nk->af; - return (PF_AFRT); - } - } - - return (PF_PASS); -} - static void pf_sctp_multihome_detach_addr(const struct pf_kstate *s) { @@ -9986,6 +9918,12 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf **m0, REASON_SET(reason, PFRES_SHORT); return (-1); } + /* + * Placeholder. The SCTP checksum is 32-bits, but + * pf_test_state() expects to update a 16-bit checksum. + * Provide a dummy value which we'll subsequently ignore. + */ + pd->pcksum = &pd->sctp_dummy_sum; break; } case IPPROTO_ICMP: { @@ -10350,7 +10288,7 @@ pf_test(sa_family_t af, int dir, int pflags, struct ifnet *ifp, struct mbuf **m0 action = pf_normalize_sctp(&pd); if (action == PF_DROP) goto done; - action = pf_test_state_sctp(&s, &pd, &reason); + action = pf_test_state(&s, &pd, &reason); if (action == PF_PASS || action == PF_AFRT) { if (V_pfsync_update_state_ptr != NULL) V_pfsync_update_state_ptr(s);