From nobody Fri Aug 11 12:13:36 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 4RMjPX4Wxvz4TjR7; Fri, 11 Aug 2023 12:13:36 +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 4RMjPX3zxlz3gfV; Fri, 11 Aug 2023 12:13:36 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1691756016; 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=yl51ye/4J616L46HISdrOIcDBIntz0twYrwnIQ7Tb10=; b=OSXaSTPVTqtf2VkkBtd5noyvxyPpL6ZjL7FnCacXGscSdKbIwM4PwGrIvrlqXBcCLreqcc gjvPipK6M/Xn8kKgiAHRzXthY6EEkbL4u3lq5jtypstcd3FEZcrtuy/7yHrwZXNWV5m1Uo EQxTjqnhyW8FrwnozykpwoNm2g3GZVBKyh5c1Bn8c9OTy/VQ7+jaH8H8hJCm257xGAxMPs VoTwOkkv/fjSy+Dt+ozUqMvAha/YIqszCKtQ2J0hWeG150GFBg1Sd1dI/VPF3PSfOqPcpe HiM0JwTlhmj9omvCgAMh2J9BvJKEGiZmWpmS0y+K0+9tviRCNFdiWVP1V7fadw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1691756016; 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=yl51ye/4J616L46HISdrOIcDBIntz0twYrwnIQ7Tb10=; b=jNaxGWzp3bmFNeO6E2SXQ8FUSXL8IoXU8mU20u26i6VltsidmOlyeG4ASY8YLkWMOq+N9U GIIaoaDpB57U/3bpG3ouxD228Lm1x9D8ZZ9VrMYVOng9vW4xCbBKtBY8JUGLvPSukhKGfa BigMYuXiTfFFmM3nWBlgCJiybEmFOE5e0kmjH9Suaz8hCnpy9Hb912os6QbC8JJQD/SAj2 FEaOkuCRKj1x2TifAeRi8GpSHZebztnnZVZd5iDXgRuDroCuRz+FYAAU8gPNj2RnTJGMkG 2gmt0o8NTffIwLQlRFaOWvjgiwDm1gJ/RjtOTYA0S9RFpVk81BHek5NM4o/1fA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1691756016; a=rsa-sha256; cv=none; b=U/bLTHPnMY2hEFUpevtQ0Mc3b3b6ZGJD4K3QWZKqUes8jLNoXJfYCyylFdlKYF5/xMQkLa aDheYed0ayP3EgskIKGc2CaQpaCkkpFMGmqHPDG/ltaD1o2eylDD9M9vC7W+cg2Dq5e11z GsQQK47PRxO2yAd7bnIUhyqUZwwM6jyneWfa27CzdqUnv6B6g6flEAmorTAVSYXvWXTAC+ Z5eQYCWtkeB6iIr+cfgzrtO+Cp1BFF0EU6nIPA6528ynIRJ1SV1mSBDQWZtHypK79HjgMK 6x6ACgfqwKOtexJf0kqWiQ5La4FgnNp9ReS9yUcptG7Vq5umfe/GEU06OoUctQ== 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 4RMjPX34z2zdpd; Fri, 11 Aug 2023 12:13:36 +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 37BCDaBt008682; Fri, 11 Aug 2023 12:13:36 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 37BCDalb008679; Fri, 11 Aug 2023 12:13:36 GMT (envelope-from git) Date: Fri, 11 Aug 2023 12:13:36 GMT Message-Id: <202308111213.37BCDalb008679@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: bd658cda0284 - stable/13 - pf: add SCTP NAT support 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: bd658cda0284209b1ce460c86b67d5b73810ec6b Auto-Submitted: auto-generated The branch stable/13 has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=bd658cda0284209b1ce460c86b67d5b73810ec6b commit bd658cda0284209b1ce460c86b67d5b73810ec6b Author: Kristof Provost AuthorDate: 2023-06-01 13:04:48 +0000 Commit: Kristof Provost CommitDate: 2023-08-11 12:13:09 +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 (cherry picked from commit 6053adafaa54204f91c43939fa334bde835403cb) --- 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 ce5e1b813bb2..5cd97c35a3f7 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -502,6 +502,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; @@ -3923,6 +3940,25 @@ pf_test_rule(struct pf_krule **rm, struct pf_kstate **sm, int direction, } 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]; @@ -5880,6 +5916,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 3190e5311ff5..a208e752e68e 100644 --- a/sys/netpfil/pf/pf_lb.c +++ b/sys/netpfil/pf/pf_lb.c @@ -237,7 +237,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. @@ -698,6 +706,10 @@ pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction, 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;