From nobody Fri Aug 11 12:13:34 2023 X-Original-To: dev-commits-src-branches@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 4RMjPV2j2Qz4q1B1; Fri, 11 Aug 2023 12:13:34 +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 "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4RMjPV1knDz3gRx; Fri, 11 Aug 2023 12:13:34 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1691756014; 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=urjITSVESrCx6nQ7ZY7QtMbx0HY12eSemJAruBSWfNc=; b=A2eimjYejSX9I6onAQp2OBNK+NXtOX1ZSoAftyf8TnWdJPKeqYxncYgszFfICBymE9lXcc pvvD++Gj3/TCPJqhryUGzZj8Ki1LvZjo/SHDcV0aViRBodEn6v6+Kz3SsSOci4mwFiKsz7 mV784n6h7ghDujJiU21TCNYphzb/I+NYLgPk8THYdNCDfXx1Ljy17Qz/4nVm6N8vrg9V9f CjhfbiXuivrUW3EzwmTmrc5odQ4H+lz57vDc3wCumjou3fe/DLIBSJ07ntTQOiMv4Hdyba Sj+pVMLWt3rfNIZOZw9hsV3FRgFg26DXGZheWO/Pg7zyFQVVlWVqfaH+PnkSCg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1691756014; 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=urjITSVESrCx6nQ7ZY7QtMbx0HY12eSemJAruBSWfNc=; b=yo8ZC5EtH4nbeo04hhRA6HCCFo3zRtaWDWSTk4fpVFfOkfPbnD4x4m7ph+9PEQlljOuAJb r6/5PCO8Q2PMcvdkJXq/cfzx9tLG0Bm+9LK6sjB5m3qYE/ptA/EuqfGqT5L0fIoE9db3oh zUcq/k31DrC/b9Qpy9j9x9G0xdr4j5RjAntnvOt82Y2nD7HdRfulkFvVqlynyNG//22sZ6 Gi/qOh+8kkrrHecAym6sGuwr6jQ8b7Nm9i2FIN0+jRrlp1jIwCmckIA/EaoSvs3m2zFZiO DuenfFjjmSAbeJngQ1C3a0GDzAciJGzWXdDU9qYSbbB58ITICa0OYSagLhdbEQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1691756014; a=rsa-sha256; cv=none; b=Ke1x2YWncHlP0uS5SA8DcjY3sf6kFzN1VC3xk0bOwrOIkxC5ny4G6Z998o01k7yw33ACer QMHplH718ZsR9DcCaYCToHTiLw1qV453+egD2PkLrA8wDA7vVzMUaTXTySGpZYAQ/rsDif 5W16fqi1ID6bTQ27Ho01IrGR4sjmdbinBfCzKxPmL3qdhEn4yPeXZSv73EwmokzFbfE+m4 rPih5UAOJHWr1j3nURu/esDIJ/V6ODeISTuJuszmoXnzTDQhrg7nYI2tvGgBxzvf/IrQqb ciqhSkcTuMmzqAjUoByWGj6stEgdN1M4tZXfP4fXaM5t85yU7U++o/QRiiXWHg== 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 4RMjPV0qcyzdgV; Fri, 11 Aug 2023 12:13:34 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 37BCDY7F008585; Fri, 11 Aug 2023 12:13:34 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 37BCDYMY008582; Fri, 11 Aug 2023 12:13:34 GMT (envelope-from git) Date: Fri, 11 Aug 2023 12:13:34 GMT Message-Id: <202308111213.37BCDYMY008582@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kristof Provost Subject: git: 540c8cd7adc5 - stable/13 - pf: support 'return' for SCTP List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: dev-commits-src-branches@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/stable/13 X-Git-Reftype: branch X-Git-Commit: 540c8cd7adc5b30fa11ea47822c333863b0663b5 Auto-Submitted: auto-generated The branch stable/13 has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=540c8cd7adc5b30fa11ea47822c333863b0663b5 commit 540c8cd7adc5b30fa11ea47822c333863b0663b5 Author: Kristof Provost AuthorDate: 2023-05-31 14:03:39 +0000 Commit: Kristof Provost CommitDate: 2023-08-11 12:13:09 +0000 pf: support 'return' for SCTP Send an SCTP Abort message if we're refusing a connection, just like we send a RST for TCP. MFC after: 3 weeks Sponsored by: Orange Business Services Differential Revision: https://reviews.freebsd.org/D40864 (cherry picked from commit d1bc1e9e1ae04016e16154884914d839566ebaec) --- sys/net/pfvar.h | 1 + sys/netpfil/pf/pf.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++ sys/netpfil/pf/pf_norm.c | 2 + 3 files changed, 120 insertions(+) diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 55bd25a3d29e..99c504d99368 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -1330,6 +1330,7 @@ struct pf_pdesc { #define PFDESC_SCTP_DATA 0x0040 #define PFDESC_SCTP_OTHER 0x0080 u_int16_t sctp_flags; + u_int32_t sctp_initiate_tag; }; #endif diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 16e0ee762f6a..ce5e1b813bb2 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -2911,6 +2911,120 @@ pf_build_tcp(const struct pf_krule *r, sa_family_t af, return (m); } +static void +pf_send_sctp_abort(sa_family_t af, struct pf_pdesc *pd, + uint8_t ttl, int rtableid) +{ + struct mbuf *m; +#ifdef INET + struct ip *h = NULL; +#endif /* INET */ +#ifdef INET6 + struct ip6_hdr *h6 = NULL; +#endif /* INET6 */ + struct sctphdr *hdr; + struct sctp_chunkhdr *chunk; + struct pf_send_entry *pfse; + int off = 0; + + MPASS(af == pd->af); + + m = m_gethdr(M_NOWAIT, MT_DATA); + if (m == NULL) + return; + + m->m_data += max_linkhdr; + m->m_flags |= M_SKIP_FIREWALL; + /* The rest of the stack assumes a rcvif, so provide one. + * This is a locally generated packet, so .. close enough. */ + m->m_pkthdr.rcvif = V_loif; + + /* IPv4|6 header */ + switch (af) { +#ifdef INET + case AF_INET: + bzero(m->m_data, sizeof(struct ip) + sizeof(*hdr) + sizeof(*chunk)); + + h = mtod(m, struct ip *); + + /* IP header fields included in the TCP checksum */ + + h->ip_p = IPPROTO_SCTP; + h->ip_len = htons(sizeof(*h) + sizeof(*hdr) + sizeof(*chunk)); + h->ip_ttl = ttl ? ttl : V_ip_defttl; + h->ip_src = pd->dst->v4; + h->ip_dst = pd->src->v4; + + off += sizeof(struct ip); + break; +#endif /* INET */ +#ifdef INET6 + case AF_INET6: + bzero(m->m_data, sizeof(struct ip6_hdr) + sizeof(*hdr) + sizeof(*chunk)); + + h6 = mtod(m, struct ip6_hdr *); + + /* IP header fields included in the TCP checksum */ + h6->ip6_vfc |= IPV6_VERSION; + h6->ip6_nxt = IPPROTO_SCTP; + h6->ip6_plen = htons(sizeof(*h6) + sizeof(*hdr) + sizeof(*chunk)); + h6->ip6_hlim = ttl ? ttl : V_ip6_defhlim; + memcpy(&h6->ip6_src, &pd->dst->v6, sizeof(struct in6_addr)); + memcpy(&h6->ip6_dst, &pd->src->v6, sizeof(struct in6_addr)); + + off += sizeof(struct ip6_hdr); + break; +#endif /* INET6 */ + } + + /* SCTP header */ + hdr = mtodo(m, off); + + hdr->src_port = pd->hdr.sctp.dest_port; + hdr->dest_port = pd->hdr.sctp.src_port; + hdr->v_tag = pd->sctp_initiate_tag; + hdr->checksum = 0; + + /* Abort chunk. */ + off += sizeof(struct sctphdr); + chunk = mtodo(m, off); + + chunk->chunk_type = SCTP_ABORT_ASSOCIATION; + chunk->chunk_length = htons(sizeof(*chunk)); + + /* SCTP checksum */ + off += sizeof(*chunk); + m->m_pkthdr.len = m->m_len = off; + + pf_sctp_checksum(m, off - sizeof(*hdr) - sizeof(*chunk));; + + if (rtableid >= 0) + M_SETFIB(m, rtableid); + + /* Allocate outgoing queue entry, mbuf and mbuf tag. */ + pfse = malloc(sizeof(*pfse), M_PFTEMP, M_NOWAIT); + if (pfse == NULL) { + m_freem(m); + return; + } + + switch (af) { +#ifdef INET + case AF_INET: + pfse->pfse_type = PFSE_IP; + break; +#endif /* INET */ +#ifdef INET6 + case AF_INET6: + pfse->pfse_type = PFSE_IP6; + break; +#endif /* INET6 */ + } + + pfse->pfse_m = m; + pf_send(pfse); +} + void pf_send_tcp(const struct pf_krule *r, sa_family_t af, const struct pf_addr *saddr, const struct pf_addr *daddr, @@ -3014,6 +3128,9 @@ pf_return(struct pf_krule *r, struct pf_krule *nr, struct pf_pdesc *pd, ntohl(th->th_ack), ack, TH_RST|TH_ACK, 0, 0, r->return_ttl, 1, 0); } + } else if (pd->proto == IPPROTO_SCTP && + (r->rule_flag & PFRULE_RETURN)) { + pf_send_sctp_abort(af, pd, r->return_ttl, r->rtableid); } else if (pd->proto != IPPROTO_ICMP && af == AF_INET && r->return_icmp) pf_send_icmp(m, r->return_icmp >> 8, diff --git a/sys/netpfil/pf/pf_norm.c b/sys/netpfil/pf/pf_norm.c index 06aa577b45a7..ac02896d0762 100644 --- a/sys/netpfil/pf/pf_norm.c +++ b/sys/netpfil/pf/pf_norm.c @@ -2037,6 +2037,8 @@ pf_scan_sctp(struct mbuf *m, int ipoff, int off, struct pf_pdesc *pd) if (pd->hdr.sctp.v_tag != 0) return (PF_DROP); + pd->sctp_initiate_tag = init.init.initiate_tag; + pd->sctp_flags |= PFDESC_SCTP_INIT; break; }