My full config looks like the following (with both mangle and routing rules):
OK, so the difference from the configuration I have used to test it that causes the two to yield different results is that in yours, 123.123.123.123 is an own address of the router whereas in mine it wasn't. This has a huge impact, because the routing rules are evaluted after the routing step that distinguishes between own (local) and other (external) addresses, whereas the mangle rules are evaluated before this step. In RouterOS 6, it used to be even more complicated as mangle rule with
action=route was the only way to bypass that own/other address distinction; in RouterOS 7, an
action=mark-routing rule bypasses it too.
So to remove the need to use mangle rules to send incoming traffic for 123.123.123.123 via Wireguard, you have to detach that address from the router itself. But doing so will cause another issue - the router will stop responding to the ARP requests regarding that address that are coming from 123.123.123.0/24.
That's actually not a big deal as there are two ways to make a router respond with its own MAC address to received ARP requests regarding external addresses. Both require that a route towards that address was available through some other interface than the one through which the ARP request comes in. But there is also a good news - you actually don't need a separate routing table, you can use
main, because a route with a longer destination prefix always takes precedence. So even though attaching
123.123.123.122/24 to
ether1 dynamically creates a route to
123.123.123.0/24 via
ether1, adding a route to
123.123.123.123/32 via some other gateway than
ether1 (in your case, the Wireguard interface) to table
main will make traffic to 123.123.123.123 take this "more specific" route. And such a route will also make it possible for the router to selectively respond the incoming ARP requests regarding 123.123.123.123:
/ip arp add address=123.123.123.123 published=yes interface=ether1 is the way to do that.