Bridge dst-nat packets disappear

Hi all,
I’m trying to understand what happens to packets that I apply bridge dst-nat to on my CRS326 with RouterOS 7.11. After the bridge dst-nat rule applies, they seem to disappear.

For context the router is routing between WAN on ether1, and LAN on bridge which includes all the other interfaces.
Regular IPv4 source NAT is working to give private IP space clients in the LAN access to WAN. Additionally one of the LAN devices is a server. I have a working IP-layer dst-nat mapping ports from the WAN to the server, and hairpin NAT rules also work so that clients in the LAN can reach the server using the WAN IP address. Maybe the only wrinkle in this setup is that the server is attached via a balance-xor bond (a member of the bridge). I don’t know. I don’t have any VLANs set up yet either.

Anyway. I wanted to try using layer 2 dst-nat instead of hairpins, like how DSR operates with load balancers: instead of substitution the dst IP address, the dst-nat rule replaces the dst MAC in the packet with that of the server, leaving the dst IP address alone. The server gets the packet, and replies directly to clients. In theory.

I configured the server with the WAN IP address on its loopback interface and I adjusted its ARP sysctls to avoid confusion. I tested that it works by setting a static route on one of the clients for the WAN IP to the server, hitting the WAN IP with traffic from that client, and tcpdump showed a normal TCP conversation without IP NAT.

When I enable the bridge dst-nat rule, the packets don’t appear. I split the rule into a packet mark rule and the dst-nat rule, and then added some passthrough rules in all the chains (input, forwarding, output, dstnat, srcnat) to see where marked packets are ending up. My understanding of the packet flow diagram is that after dstnat, a packet should go through forwarding and srcnat. With the dst-nat rule disabled, the passthrough counters agree with this. But with the dst-nat rule enabled, although the dst-nat rule counters go up, none of the passthrough counters go up.

Since I’m applying dst-nat at the bridge layer between two bridge ports, and not using queues or VLANs, I don’t see the need for use-ip-firewall, but maybe I’ve misunderstood the manual.

Where are the packets going?

Here’s “interface bridge export” with some details redacted:

# 2023-09-01 16:28:29 by RouterOS 7.11
# software id = RM5U-C08Y
#
# model = CRS326-24G-2S+
# serial number = <redacted>
/interface bridge
add admin-mac=<redacted> auto-mac=no comment=LAN name=bridge
/interface bridge filter
add action=passthrough chain=input comment=marked packet-mark=mark
add action=passthrough chain=forward comment=marked packet-mark=mark
add action=passthrough chain=output comment=marked packet-mark=mark
/interface bridge nat
add action=mark-packet chain=dstnat comment="mark" dst-address=<WAN IP address>/32 \
    dst-port=80 ip-protocol=tcp mac-protocol=ip new-packet-mark=mark src-address=\
    <LAN client for testing>/32
add action=dst-nat chain=dstnat comment="dnat -> server" packet-mark=mark \
    to-dst-mac-address=<server MAC addr>
add action=passthrough chain=dstnat comment=marked packet-mark=mark
add action=passthrough chain=srcnat comment=marked packet-mark=mark
/interface bridge port
add bridge=bridge disabled=yes ingress-filtering=no interface=ether1
add bridge=bridge ingress-filtering=no interface=ether2
<etc etc>
add bridge=bridge ingress-filtering=no interface=ether22
add bridge=bridge disabled=yes ingress-filtering=no interface=ether23
add bridge=bridge disabled=yes ingress-filtering=no interface=ether24
add bridge=bridge ingress-filtering=no interface=sfp-sfpplus1
add bridge=bridge ingress-filtering=no interface=sfp-sfpplus2
add bridge=bridge comment=server interface=bonding1

Is this a bug in RouterOS?

Can we agree the packet path taken by Layer 2 MAC translation and Layer 3 IP address translation is the same path in both cases?

The standard practice for private address servers is split-horizon DNS where DNS server resolves server hostname with private or public address depending on which source address the clients use to query the DNS server. If CRS326 is only network device then the packet path once again is unchanged.

The posted configuration comes across as very unusual and IMO raises concern the approach may disable hardware offload giving up switch chip wire speed.
IMO this looks like an XY Problem where the initial presentation is a possibly flawed solution with nothing said about the real goals and requirements.
Network diagram or brief & comprehensive description of subnets, a count of servers and clients, and key server and/or client specifics, all help.
Getting the most out of this forum by normis, MikroTik Support

I see a loop hole in the description above: server would need WAN IP address defined on its LAN interface.
Without that, in theory bridge-NATed frame would be accepted by server’s NIC (because of matching MAC address) and it would be passed to server’s IP stack. Which in turn would either forward it towards seemingly better destination (if IP routing is enabled on server) or simply drop it.

You should be able to check if there’s some merrit in my theory by running wireshark on server … if I’m right, you should see ethernet frames with server’s MAC as destination and WAN IP address as destination address.

Thank you for your responses.

You are correct that this is an instance of “XY Problem”. I have an already working solution - a hairpin NAT rule (or, as suggested, I could just as easily get split-horizon DNS working).

But. I asked a question because I tried something, the results did not make sense, and so I must have misunderstood something. Please kindly consider my “X” problem in this instance to be my curiosity.

I expected that, with the bridge dst-nat rule enabled:

  • a tcpdump on the server would see incoming packets
  • packet counts for matching rules that come after bridge dst-nat in the Packet Flow would increment
    Neither of those things happen.

I’ll try to provide some more details soon.

I believe I showed via testing (with a temporary static route on a client) that the server configuration (with the WAN IP configured on a loopback interface) is sufficient. The server does not have forwarding enabled, so I would expect the packets to be either accepted or dropped. It connected, tcpdump showed a normal TCP conversation, etc