Hello aruhn,
I think you are going about this all wrong. This is a bit tricky, so here are some important plot points:
1) Don't mess with Apple's stuff. That launchd config file should be protected by SIP (System Integrity Protection), AKA "rootless", so you shouldn't be able to edit it at all. Did you turn SIP off? If so, turn it back on. You don't need to turn it off.
2) Don't mess with Apple's stuff. pfctl is a special case. Normally, if you wanted to override the way Apple was running some system utility, you would use "sudo launchtl unload -w" to turn off the system version. Then copy the launchctl plist file to /Library/Launch(Agents|Daemons), rename it, change the label to one of your own, and load it from there.
3) pfctl is a special case. You should leave the system version running. Go ahead and copy the system launchctl plist file from /System/Library/LaunchDaemons/com.apple.pfctl.plist to /Library/LaunchDaemons and give it a meaningful name. I named mine "com.etresoft.pfctl.plist". Change the label too. Again, I used "com.etresoft.pfctl.plist". Now when I type "sudo launchctl list | grep pfctl" I can see exactly what is going on. And again, this is because pfctl is a special case. See point 2) for most other things.
4) There are some additional tricky bits to running pfctl from launchd. This thread was very helpful (where to put pfctl rules to make them persistent). It points to this gist which explains about a potential stderr issue (https://gist.github.com/lowescott/5581726). I'm not sure if this is really necessary or not. Add this logic and get it working, then try to remove it. I'm just to lazy to do that and restart again because I've already got half this response typed out . Finally, I'm not really a pfctl expert. This page was very helpful for debugging techniques (https://salferrarello.com/mac-pfctl-port-forwarding/). Update: curiosity got the better of me. Ignore that gist and read below.
5) There is some discrepancy between the files you are referencing. /etc/pf.conf is the system file, not /etc/pfctl.conf.
6) Regardless, you don't want to modify /etc/pf.conf. Important plot point: never modify Apple's system files in /etc is there is any way around it. If you absolutely must modify one, use the "ditto" command to make a backup and try real hard to restore the original (in content and date) once you have it figured out. Otherwise, if Apple issues a software update and changes one of these files, say for a security issue, you may be left with your old, modified version forever.
7) You also seem to be talking about loading that anchor file the same way Apple is doing it. These config files support complex structures for complex situations. This is a simple situation. Just add your rules to a file in /etc or /etc/pf.anchors and reference the file directly.
8) Regarding point 4) above. The author of that gist was wrong about the stderr issue. This is a complicated topic and it doesn't surprise me that someone might misunderstand something, get it wrong, and think something like this is required. In fact, even Apple might be getting this wrong. The stderr issue is a convenient side effect that seems to be preventing an infinite loop. I'll explain this interesting part at the end.
9) If you've read all of these points and still haven't lost interest entirely, congratulations! I'll reward you with a working launchd config file. Save this file to /Library/LaunchDaemons and give it a name and label that is meaningful to you:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE plist PUBLIC "-//Apple Computer/DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.etresoft.pfctl.plist</string>
<key>Program</key>
<string>/sbin/pfctl</string>
<key>ProgramArguments</key>
<array>
<string>/sbin/pfctl</string>
<string>-e</string>
<string>-f</string>
<string>/etc/pf.anchors/com.etresoft</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>LaunchOnlyOnce</key>
<true/>
</dict>
</plist>
and here is my /etc/pf.anchors/com.etresoft file:
rdr pass on lo0 inet proto tcp from any to 127.0.0.1 port 8888 -> 127.0.0.1 port 80
rdr pass on lo0 inet6 proto tcp from any to fe80::1%lo0 port 8888 -> fe80::1%lo0 port 80
In my case, I'm redirecting 8888 to port 80 just to test. Note that I included IPv6. That part was tricky. I'm not an ethernet expert either. ::1 caused strange localhost issues. This versions works after a restart.
That bit about the stderr is interesting. If you investigate launchctl list, you will see that Apple's task exits with a status code 1. launchctl considers anything not 0 to be failure. At that point, it gets complicated about whether or not to restart. In my launchd file, I explicitly added the LaunchOnlyOnce key. Now I don't need to bother to study the details about how launchd might or might now respawn failed jobs. I've set the script to be run only once regardless. Because pfctl is special, this is all I need.
Technically speaking, adding those stderr and stdout redirects are correct. That would prevent pfctl from exiting with 1. But, pfctl still works regardless. That is how it launches to begin with. Maybe I will file a bug report about this. I don't know. I kind of like seeing the output from launchctl list. When I had my script configured to map stderr and return 0, after it runs once and exits, it no longer shows up in launchctl list. That's very curious for other reasons.
So, to recap. Undo whatever you have done to hack up your system. Restore these config files to their default values. Ideally, restore them from backup so the dates and times are correct too. Restore your system security. Turn SIP back on. Tturn GateKeeper back on too if you have turned that off like everyone else on the internet seems to have done. Then add your own pfctl anchor file. Add your own launchd config script, and start redirecting some packets.
PS: And thanks for an interesting question. It made me think. I haven't seen a good one like this in a long time.