From nobody Fri Jul 21 10:32:42 2023 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 4R6m8v4ggwz4pFvP; Fri, 21 Jul 2023 10:32:43 +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 4R6m8p4NvTz3qSC; Fri, 21 Jul 2023 10:32:42 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1689935562; 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=MT0gV93MqexUBEnfmWwSQLyNsGCLt0qa5x2lHMfKPT8=; b=gMTLElFmFQ/NbzN7NzXzDxaZ7P0fD7QbCXFiipKP0jd5Qs07RSsIL6lIZ8WxZD7/Mo6jQq txfYIrGY1PBHsEOqht2c7105sMZx0gTABVpefnaTIbuY1haaQpF2v6ygy+/TgTuwjx38V1 mpO6L8Dgw72R5b3RAS4lLWAkf9rzkhw9k9Uf9wd9HXLS3rPfJRr1cWHmN+PzPkuv4CKlyx 0MTzoBbZ+A7No6+uYmChLu8z0qimRJnuy5ncoGyy8hzlxaU0HRy9GqPccAhpkBzDHR9+p4 j7AUOlkKLU9mMaLUxwXLY+ec+0kYPTkoOWqMweMdsI2UPwR0rijAcdW4KlcbLA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1689935562; 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=MT0gV93MqexUBEnfmWwSQLyNsGCLt0qa5x2lHMfKPT8=; b=UQ0OssY7nsS1T8O5RCONlF+OEz2VC+tJu1Kr6Sl0iHb28O/xYCK000etsXFTphSspjgPEp SOjR0d4JM9bF1FZRjYWN6y0Av7QBxwFZ3X9Os0JMdMt+sjXwzobO2Eh201gb5BGFNkwKzp mb4nOJajuPxNdB8G5db93gTTGpVTqYAttOyEludRHHOt7vDssEDaZBb5NZq/cII9ufslfF ionbyMtjD+6XwImt/uEyCs5cz3WCBrc08PazJDnykxH6uxrUF0Z3xmJMCoaavf5l64gBU1 knT51+qIcpKR2dgjd/HmX0gjDBK9wARXZE5hShTLhZO1tDhJnWbn+kLILyM40w== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1689935562; a=rsa-sha256; cv=none; b=ne5FLqdFEey5YTAPfSSVOAgTcvHuzA6RBznbvPf4ue8+LMjORoyXweI2h1HpW4y46y2mCw QMjcR5AJut37vAQqY7Q8l/9VmYc/qafW4arVBiX5DzeZjWxakyJxIndFJHdVaJIPlQxbIG nKbZWTbAHukjYdh+0bjd0WzXlbqcEbuDdDuTHu5GO51WxQlcew+06Nk9LMKcCTfIyL4BV5 esndZChWBQagjw9rU3pWh8plYWYdID0S+ohqPu78H5TOaZTsxMEzisPXV3oDW9v7vk90Zs o2+jz6yfKn2CAUx20oYK1ahvGNPUK5g9Y3+6ZPYleoRdLwS5Sjk4VKTJSRtLCw== 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 4R6m8p36nqz18G7; Fri, 21 Jul 2023 10:32:42 +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 36LAWgQa010596; Fri, 21 Jul 2023 10:32:42 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 36LAWg4A010595; Fri, 21 Jul 2023 10:32:42 GMT (envelope-from git) Date: Fri, 21 Jul 2023 10:32:42 GMT Message-Id: <202307211032.36LAWg4A010595@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: 6053adafaa54 - main - pf: add SCTP NAT support 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: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: 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: 6053adafaa54204f91c43939fa334bde835403cb Auto-Submitted: auto-generated The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=6053adafaa54204f91c43939fa334bde835403cb commit 6053adafaa54204f91c43939fa334bde835403cb Author: Kristof Provost AuthorDate: 2023-06-01 13:04:48 +0000 Commit: Kristof Provost CommitDate: 2023-07-21 10:32:19 +0000 pf: add SCTP NAT support Support NAT-ing SCTP connections. This is mostly similar to UDP and TCP, but we refuse to change ports for SCTP, to avoid interfering with multihomed connections. As a result we also never copy the SCTP header back or recalculate checksums as we'd do for TCP or UDP (because we don't modify the header for SCTP). We do use the existing pf_change_ap() function to modify the packet, because we may still need to update the IPv4 header checksum. Reviewed by: tuexen MFC after: 3 weeks Sponsored by: Orange Business Services Differential Revision: https://reviews.freebsd.org/D40866 --- sys/netpfil/pf/pf.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++ sys/netpfil/pf/pf_lb.c | 14 ++++++++++++- 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 70a00147ccf2..9162f8cf949b 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -528,6 +528,23 @@ pf_packet_rework_nat(struct mbuf *m, struct pf_pdesc *pd, int off, m_copyback(m, off, sizeof(*uh), (caddr_t)uh); break; } + case IPPROTO_SCTP: { + struct sctphdr *sh = &pd->hdr.sctp; + uint16_t checksum = 0; + + if (PF_ANEQ(pd->src, &nk->addr[pd->sidx], pd->af)) { + pf_change_ap(m, pd->src, &sh->src_port, pd->ip_sum, + &checksum, &nk->addr[pd->sidx], + nk->port[pd->sidx], 1, pd->af); + } + if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], pd->af)) { + pf_change_ap(m, pd->dst, &sh->dest_port, pd->ip_sum, + &checksum, &nk->addr[pd->didx], + nk->port[pd->didx], 1, pd->af); + } + + break; + } case IPPROTO_ICMP: { struct icmp *ih = &pd->hdr.icmp; @@ -4472,6 +4489,25 @@ pf_test_rule(struct pf_krule **rm, struct pf_kstate **sm, struct pfi_kkif *kif, } rewrite++; break; + case IPPROTO_SCTP: { + uint16_t checksum = 0; + + if (PF_ANEQ(saddr, &nk->addr[pd->sidx], af) || + nk->port[pd->sidx] != sport) { + pf_change_ap(m, saddr, &pd->hdr.sctp.src_port, + pd->ip_sum, &checksum, + &nk->addr[pd->sidx], + nk->port[pd->sidx], 1, af); + } + if (PF_ANEQ(daddr, &nk->addr[pd->didx], af) || + nk->port[pd->didx] != dport) { + pf_change_ap(m, daddr, &pd->hdr.sctp.dest_port, + pd->ip_sum, &checksum, + &nk->addr[pd->didx], + nk->port[pd->didx], 1, af); + } + break; + } #ifdef INET case IPPROTO_ICMP: nk->port[0] = nk->port[1]; @@ -5856,6 +5892,26 @@ pf_test_state_sctp(struct pf_kstate **state, struct pfi_kkif *kif, (*state)->expire = time_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 = (*state)->key[pd->didx]; + + if (PF_ANEQ(pd->src, &nk->addr[pd->sidx], pd->af) || + nk->port[pd->sidx] != pd->hdr.sctp.src_port) { + pf_change_ap(m, pd->src, &pd->hdr.sctp.src_port, + pd->ip_sum, &checksum, &nk->addr[pd->sidx], + nk->port[pd->sidx], 1, pd->af); + } + + if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], pd->af) || + nk->port[pd->didx] != pd->hdr.sctp.dest_port) { + pf_change_ap(m, pd->dst, &pd->hdr.sctp.dest_port, + pd->ip_sum, &checksum, &nk->addr[pd->didx], + nk->port[pd->didx], 1, pd->af); + } + } + return (PF_PASS); } diff --git a/sys/netpfil/pf/pf_lb.c b/sys/netpfil/pf/pf_lb.c index 98e1a2d32488..3055741f1fc0 100644 --- a/sys/netpfil/pf/pf_lb.c +++ b/sys/netpfil/pf/pf_lb.c @@ -240,7 +240,15 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_krule *r, * port search; start random, step; * similar 2 portloop in in_pcbbind */ - if (!(proto == IPPROTO_TCP || proto == IPPROTO_UDP || + if (proto == IPPROTO_SCTP) { + key.port[1] = sport; + if (!pf_find_state_all_exists(&key, PF_IN)) { + *nport = sport; + return (0); + } else { + return (1); /* Fail mapping. */ + } + } else if (!(proto == IPPROTO_TCP || proto == IPPROTO_UDP || proto == IPPROTO_ICMP) || (low == 0 && high == 0)) { /* * XXX bug: icmp states don't use the id on both sides. @@ -711,6 +719,10 @@ pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, PF_POOLMASK(naddr, naddr, &r->rpool.cur->addr.v.a.mask, daddr, pd->af); + /* Do not change SCTP ports. */ + if (pd->proto == IPPROTO_SCTP) + break; + if (r->rpool.proxy_port[1]) { uint32_t tmp_nport;