OpenBSD and pf really is the best. As noted above, FreeBSD has wandered off into the weeds with pf for no good reason. There have been so many improvements to pf since 2009 that I wouldn't even consider using something that old.
I used pfSense years ago when I was first learning firewalls. These days the best GUI for me is no GUI but a CLI, but some people don't want to take the time to build a firewall. Granted, once you know how to do it, it doesn't take that much time to build a firewall, but it does take time to understand what you're doing and why. But really, not that much time, considering the aggravation it can save you down the road.
One is the past behavior of one developer who claimed to reverse engineer code that obviously wasn't.
The other is a mistake made in 2003, to which they've still not owned up.
You don't silently patch security issues, especially when they are discovered and fixed by someone outside the project.
Other than these, I have nothing but admiration for the project and it's developers.
It is true that FreeBSD's pf lacks some of the recent improvements which have been made in OpenBSD's pf.
It is also true that OpenBSD's pf lacks some of the recent improvements which have been made in FreeBSD's pf.
pfsense uses FreeBSD's fork of pf, which is years out of date. They forked in order to add multithreading, ostensibly for performance. But the diff is too complicated to keep rebasing on top of upstream, so they're stuck with a pf from 2009.
Here are a few resources to get you started. You'll learn plenty about routing!
https://www.openbsd.org/faq/pf/example1.html
https://www.22decembre.eu/2016/05/27/openbsd-router-en/
Compared to Linux, OpenBSD is starkly minimal. It can be a little bewildering when common programs seem to be missing, but the man pages are outstanding. And the system is very simple and reliable. Config files are almost comically short. My /etc/hostname.re0 config is just five bytes: `dhcp\n`.