git: e2177bca94f2 - main - pf: allow pf_get_sport() to work on in rules
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 16 Apr 2025 18:02:56 UTC
The branch main has been updated by kp:
URL: https://cgit.FreeBSD.org/src/commit/?id=e2177bca94f28613ab4a47ef6d3469f80e8d5923
commit e2177bca94f28613ab4a47ef6d3469f80e8d5923
Author: Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2025-04-16 08:47:58 +0000
Commit: Kristof Provost <kp@FreeBSD.org>
CommitDate: 2025-04-16 14:23:48 +0000
pf: allow pf_get_sport() to work on in rules
The function pf_get_sport() did work for out rules only. Make it
aware of the direction of the packet. Now nat-to can be used by
in rules and together with divert-to. Collisions with existing
states are found and produce a "NAT proxy port allocation failed"
message.
OK henning@ mikeb@
Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, 4af3c109db
Sponsored by: Rubicon Communications, LLC ("Netgate")
---
sys/netpfil/pf/pf_lb.c | 32 ++++++++++++++++++--------------
1 file changed, 18 insertions(+), 14 deletions(-)
diff --git a/sys/netpfil/pf/pf_lb.c b/sys/netpfil/pf/pf_lb.c
index 9785611271a0..d40f4828eb62 100644
--- a/sys/netpfil/pf/pf_lb.c
+++ b/sys/netpfil/pf/pf_lb.c
@@ -226,6 +226,9 @@ pf_get_sport(struct pf_pdesc *pd, struct pf_krule *r,
{
struct pf_state_key_cmp key;
struct pf_addr init_addr;
+ int dir = (pd->dir == PF_IN) ? PF_OUT : PF_IN;
+ int sidx = pd->sidx;
+ int didx = pd->didx;
bzero(&init_addr, sizeof(init_addr));
@@ -291,11 +294,12 @@ pf_get_sport(struct pf_pdesc *pd, struct pf_krule *r,
bzero(&key, sizeof(key));
key.af = pd->naf;
key.proto = pd->proto;
- key.port[0] = pd->ndport;
- PF_ACPY(&key.addr[0], &pd->ndaddr, key.af);
do {
- PF_ACPY(&key.addr[1], naddr, key.af);
+ PF_ACPY(&key.addr[didx], &pd->ndaddr, key.af);
+ PF_ACPY(&key.addr[sidx], naddr, key.af);
+ key.port[didx] = pd->ndport;
+
if (udp_mapping && *udp_mapping)
PF_ACPY(&(*udp_mapping)->endpoints[1].addr, naddr, pd->af);
@@ -304,8 +308,8 @@ pf_get_sport(struct pf_pdesc *pd, struct pf_krule *r,
* similar 2 portloop in in_pcbbind
*/
if (pd->proto == IPPROTO_SCTP) {
- key.port[1] = pd->nsport;
- if (!pf_find_state_all_exists(&key, PF_IN)) {
+ key.port[sidx] = pd->nsport;
+ if (!pf_find_state_all_exists(&key, dir)) {
*nport = pd->nsport;
return (0);
} else {
@@ -317,14 +321,14 @@ pf_get_sport(struct pf_pdesc *pd, struct pf_krule *r,
* XXX bug: icmp states don't use the id on both sides.
* (traceroute -I through nat)
*/
- key.port[1] = pd->nsport;
- if (!pf_find_state_all_exists(&key, PF_IN)) {
+ key.port[sidx] = pd->nsport;
+ if (!pf_find_state_all_exists(&key, dir)) {
*nport = pd->nsport;
return (0);
}
} else if (low == high) {
- key.port[1] = htons(low);
- if (!pf_find_state_all_exists(&key, PF_IN)) {
+ key.port[sidx] = htons(low);
+ if (!pf_find_state_all_exists(&key, dir)) {
if (udp_mapping && *udp_mapping != NULL) {
(*udp_mapping)->endpoints[1].port = htons(low);
if (pf_udp_mapping_insert(*udp_mapping) == 0) {
@@ -350,14 +354,14 @@ pf_get_sport(struct pf_pdesc *pd, struct pf_krule *r,
/* low <= cut <= high */
for (tmp = cut; tmp <= high && tmp <= 0xffff; ++tmp) {
if (udp_mapping && *udp_mapping != NULL) {
- (*udp_mapping)->endpoints[1].port = htons(tmp);
+ (*udp_mapping)->endpoints[sidx].port = htons(tmp);
if (pf_udp_mapping_insert(*udp_mapping) == 0) {
*nport = htons(tmp);
return (0);
}
} else {
- key.port[1] = htons(tmp);
- if (!pf_find_state_all_exists(&key, PF_IN)) {
+ key.port[sidx] = htons(tmp);
+ if (!pf_find_state_all_exists(&key, dir)) {
*nport = htons(tmp);
return (0);
}
@@ -374,8 +378,8 @@ pf_get_sport(struct pf_pdesc *pd, struct pf_krule *r,
return (0);
}
} else {
- key.port[1] = htons(tmp);
- if (!pf_find_state_all_exists(&key, PF_IN)) {
+ key.port[sidx] = htons(tmp);
+ if (!pf_find_state_all_exists(&key, dir)) {
*nport = htons(tmp);
return (0);
}