So what you want and expect is that a packet sent from a device in 192.168.9.0/24 to the public IP address attached to ether2 port 11111 will go out via ether1 or ether3 depending on the PCC outcome, get src-nated to the public address of ether1 or ether3, and land on ether2 after passing through the internet. And then your dst-nat rule should forward that packet to 192.168.12.200. The response of the Wireguard peer on 192.168.12.200 should then go out via ether2, get un-dst-nated to the public IP of ether2, reach ether1 or ether3 depending on the source address of the initial request, get un-src-nated there and be delivered to 192.168.9.x, which has sent that request.
Is that a correct understanding?
If yes, the good news is that the port-forwarding rule is fine (for Wireguard, the UDP one is enough, the TCP one is not necessary).
The bad news is that your firewall is basically non-existent as the default handling in all firewall chains is “accept”, so packets that didn’t match to any rule in that chain get accepted. So your firewall filter accepts packets belonging to dst-nated connections explicitly and all other packets implicitly.
But leaving security aside, there are multiple issues with your mangle rules that prevent the expected flow as outlined above from happening:
- the mangle rules you want to assign a connection mark toether1-youbroad or toether3-tata to the initial request packet from 192.168.9.x to ip.of.ether.2 ignore that packet because there is a match condition dst-address-type=!local in these rules. Years ago someone has misunderstood the meaning and behavior of the dst-address-type match condition and posted rules that included it, and worse than that, many people who copy-paste without understanding have since posted their own configurations with the same mistake. The original intention was to prevent traffic between LANs of the same router from getting routed outside, but dst-address-type=!local doesn’t do even that. What it actually does is that it prevents the rule from acting on packets whose destination address is any of the own addresses of the router (i.e. the WAN ones included).
So the initial request doesn’t get any connection mark, hence it doesn’t get any routing mark, and therefore it is delivered locally and never leaves the router, so the dst-nat rule matching on in-interface-list=WAN ignores it, and so does the router itself as no local service listens at UDP port 11111.
In your case, local traffic between 192.168.9.0/24 and 192.168.12.0/24 is not required, so you don’t need to exempt corresponding packets from getting the connection marks and, subsequently, routing mark causing them to be routed via WAN, so it might seem there is no need to replace the incorrect match condition by a correct one and that it is enough to remove the incorrect dst-address-type=!local one. However, since you are running a newer RouterOS 7 than 7.6 or so, the presence of routing mark affects more routing decisions than it did before -namely, the fact that the destination address is one of router’s own ones doesn’t prevent the packet from getting routed according to the routing mark any more. Hence just removing that match condition would prevent the devices in LAN from talking to the Mikrotik itself. If this is an issue for you (e.g. because you want to manage the 4011 from LAN while connecting to its IP address rather than MAC address), you have to replace that match condition by e.g. dst-address=!192.168.0.0/16.
Once you do this, the initial request packet will start leaving through ether1 or ether3 and should return via ether2. - once the initial request packet arrives to ether2, it creates a new tracked connection, and thanks to the prerouting rule matching on in-interface=ether2-hathway, the connection will get a connection mark ether2-hathway-in. However, the only mark-routing rule that matches on this connection mark and “translates” it to routing mark tohathway is in mangle chain output, which only handles packets sent by the router itself, not those it forwards from one interface to another - these are handled in prerouting. But there, the only rule assigning the routing mark tohathway matches on a different connection mark, toether2-hathway, which is only assigned by the rules handling the transit traffic in prerouting. So the response packet ends up without any routing mark and thus gets locally delivered to the IP address of ether1 or ether3, where no local process expects it so it gets dropped.
Since the only purpose of both those connection marks is the same, to get “translated” to the same routing mark tohathway, the easiest way to solve this to replace ether2-hathway-in by toether2-hathway in all rules that assign it or match on it. While at it, I’d suggest you to do the same for the connection marks related to ether1 and ether3.