Thanks for the offer, although I already have it working. I will explain it for other people's benefit, though.
I want to rdr certain ports to certain internal hosts using pf, at the same time as using NAT on the external interface. The rdr rules work fine for this, but as you noted, internal hosts cannot connect to the external ip address with the single rdr rule. So you add a rdr rule on the internal NIC, right? Wrong. That's what that quote from the pf documentation is about--such a method doesn't work.
3 Hosts, let's give them real IPs just to be clear:
Gateway ($int) 10.0.0.1 ($ext) 184.108.40.206
We do NAT on ext, and redirect port 5555 to Host2:
nat on $ext proto $tcp from 10.0.0.0/24 to any -> $ext
rdr on $ext proto tcp from any to $ext port 5555 -> Host2 port 5555
Any external host connects to 220.127.116.11, the port is forwarded using the rdr rule. Host2 sees the forward, responds to the external host, and everything works.
But what if Host3 connects to 18.104.22.168? It doesn't work, so we add another rdr rule (as you suggested):
rdr on $int proto tcp from any to $ext port 5555 -> Host2 port 5555
Host3 sends a packet to 22.214.171.124, which comes in on $int. Packet looks like this:
Src: 10.0.0.3; Dest=126.96.36.199
Then, pf redirects the packet to 10.0.0.2. So far, so good. Host2 responds, with a packet like this:
Src: 10.0.0.2; Dest 10.0.0.3
Host3 sees this packet and throws it away. Host3 says, essentially "I never sent anything to 10.0.0.3--why is it responding?" The rdr rule will never work because the wrong host responds to Host3's request to connect to 188.8.131.52.
The solution from OpenBSD's pf page is to add a NAT rule that changes the source ip:
nat on $int proto tcp from 10.0.0.0/24 to Host2 port 5555 -> $int
What this does is make the initial packet appear to come from $int. Host2 then responds to $int, where pf's NAT will translate the source ip back to 184.108.40.206, so that Host3 thinks it's talking to 220.127.116.11. As the page notes, this is not exactly an elegant solution, but it works (they add another rule to tighten it a bit).
I don't believe simply adding an rdr as you did in the article works, although I may have misunderstood your configuration. The internal rdr does forward the port, but the responding packet will be dropped as it comes from the wrong host. NAT similar to the external interfaces is needed in order to make the internal host believe it is talking to the external ip.