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); }