I've used shorewall for some time. As a matter of fact, installed it on my recent laptop as well (archlinux). But till now I didn't like quite often config file format changes, because of which I needed to figure out how to change current config to match the latest one. PF in this regard was more consistent and more readable and didn't requre to use anything on top of it. Then again - I never needed very complex FW rules.
Never needed to do something with layer2. I used it mostly for educational purposes for my home network. Can you name some real world examples when OSI layer2 filtering is needed?
I use layer 2 filtering on my home network in order to get direct internet access without going through my "mandatory" ISP-provided gateway that authenticates the port with 802.1x EAP-TLS.
A complex iptables ruleset is difficult to understand, while a pf.conf almost reads like prose.
Feature-wise, netfilter is richer, if only for the fact that there are more contributors. On the other hand, iptables and other frontends I've had the opportunity to use (ufw, firewalld) down right suck. Did I mention that most HOWTOs regarding iptables lead you down a wrong path, which is writing your ruleset as a shell script which calls the iptables / ip6tables binaries. If you fat finger a rule and run the script, you'll end up loading half the ruleset (which could be harmless, but you could very well lock yourself out a server if doing this remotely). PF rules are loaded atomically using the pfctl tool: either you get the whole new ruleset inplace, or you keep the old one. I believe the same behavior can be obtained with iptables-save/restore.
PF feels much more coherent and also has fantastic documentation. The OpenBSD FAQ as well as the pf.conf and pfctl cover most things you need to know regarding PF (there's also a book by Peter Hansteen called "The Book of PF" that is an excellent resource).
netfilter on the hand feels much more "stitched together". You want to configure IPv4 rules ? iptables. IPv6 ? ip6tables. You have rules tracking state? conntrack. The documentation around each of these tools is of varying quality. The one I'm having most trouble with is "tc", but that may because I don't grok queueing/traffic shaping/QoS yet. I have no experience with the latter on OpenBSD so I can not comment.
Can't answer the first question, but for me the pf syntax for firewall rules, NAT and inbound port forwarding is much simpler.
I don't trust any box running 300 out-of-date packages plus a PHP GUI, so my edge device is simply a dual-ethernet 8W device that runs OpenBSD with the following rules:
set skip on lo0
block all
pass out on en0 inet from en1:network to any nat-to (en0) // source NAT