MikroTik field tools · Firewall expertise · free · in-browser

The RouterOS packet flow, interactive

This is the forward path, the route a packet takes through your router from one interface to another. A packet addressed to the router itself leaves this path at the routing decision for the input chain, and the diagram doesn't follow it there. I draw eight stages. Select one and the panel shows what a drop there costs and what a rule there can still see, the two things I check when deciding where a rule belongs. Run the trace and watch the cost climb as the same packet moves on, from nearly free at RAW to most expensive at filter. The diagram leaves out mangle postrouting, which runs between filter and source NAT, and the queues after source NAT.

Trace a packet

Point the same flood at two routers. Drop it in the filter chain and every packet has already paid for a connection-tracking entry and the CPU to carry it that far by the time your rule sees it. Drop it in RAW instead, before tracking runs at all, and it costs almost nothing. Both rules drop the same packets. The cost depends on where in the flow the rule sits. Pick a stage below to see what it costs and what it can still see, then run the trace.

The RouterOS forward-path packet pipeline, in order: a packet arrives, then RAW, connection tracking, mangle prerouting, destination NAT, the routing decision, mangle forward, filter forward, and source NAT, before it leaves. Where a rule sits in this order decides what it costs and what it can still see.A single left-to-right pipeline. A forwarded packet meets each checkpoint in a fixed order: RAW (the cheapest place to drop, before any tracking), connection tracking (where cost begins), mangle prerouting, destination NAT, the routing decision (a diamond — forward or local), mangle forward, filter forward (the firewall proper, still seeing the real source), and source NAT (masquerade, on the way out). A cost ledger below the row leaps the instant tracking turns on.
RAWprerouting/ip firewall raw
What it does
The earliest place you can act on a packet — before the router spends anything tracking it.
What it sees
The bare packet only. There is no connection state yet — nothing to match on but the packet itself.
The insight
Drop a flood here and it costs almost nothing — you shed it before the router opens a single tracking entry. The cheapest possible drop, and it is cheap only because of where it sits.
Cost so far
Nothing allocated yet — a drop here is essentially free.

a drop here — vs a drop at FILTER

RAW, before connection tracking — the earliest and cheapest place to drop. Nothing is tracked yet.

How I decide where a rule belongs

Find the first stage that sees what you're matching

Before you write the rule, work out where in this order your target is actually visible — the bare packet, a tracked connection, a real address, a routed decision. Most misplaced rules come from skipping this step: a rule that's correct in isolation but sits in the wrong stage of the flow, matching something that isn't there yet or has already changed.

Drop floods in RAW, not filter

If the goal is just to shed unwanted traffic — a scan, a flood, anything you'll never accept — do it in RAW. It's the earliest point where you can act on an arriving packet, running before connection tracking opens an entry, so the drop costs almost nothing. The same drop written in the filter chain is correct but expensive: by then the packet has already paid for a tracking entry and the CPU to carry it that far.

Mark the connection in mangle prerouting, not the packet

If the goal is to steer where a packet gets routed — policy routing — set the mark in mangle prerouting, before the routing decision, and mark the connection rather than the packet. Connection tracking then carries that one mark to every packet in both directions of the flow; a routing mark set from it keeps each packet, replies included, on the route you chose.

Port-forward with dst-nat, before routing runs

Destination NAT sits in prerouting, ahead of the routing decision — which is why a port-forward works: rewrite the destination first, and the router then routes on the new address. A rewrite after the routing decision would come too late; the packet would already be on its way to the old destination.

Filter transit traffic in forward — the real source is still visible

Write your accept/drop rules for traffic passing through the router in the forward chain, before source NAT runs. At this point you're still looking at the genuine source address, not whatever masquerade is about to replace it with — so an address-list match here judges the actual client, not the router.

Masquerade last, in source NAT

Save the source rewrite for last, in postrouting. By the time source NAT runs, filtering has already judged the real address. What leaves the router — and what the outside world can trace back — is only the router’s own address from here on.

The questions the flow actually raises

What order do RouterOS firewall and NAT chains actually run in?

For a packet crossing the router — not one addressed to the router itself — the order is fixed: RAW prerouting, connection tracking, mangle prerouting and destination NAT; then the routing decision; then mangle forward and filter forward; then mangle postrouting, source NAT and the queues. This map draws the eight stages that set cost and visibility; mangle postrouting and the queues aren't drawn. A packet addressed to the router branches off at the routing decision into its own input chain instead, and this map doesn't follow that branch.

Why drop a flood in RAW instead of the filter chain?

A drop in RAW happens before the router opens a connection-tracking entry for that packet, so it costs almost nothing. The identical drop in the filter chain happens after conntrack has allocated that entry and the packet has been carried through mangle and NAT, which makes filter the most expensive place to drop it. RAW sees only the bare packet, with no connection state, so it suits traffic you can refuse on sight. Drop at the earliest stage that can still match the traffic.

Why does destination NAT run before the routing decision?

Because RouterOS needs the real destination settled before it can route on it. Dst-nat sits in the prerouting chain, ahead of the routing decision — so when a port-forward rewrites where a packet is going, the router then routes on that new address. That ordering is what makes a port-forward actually reach an inside service instead of just relabeling a packet that's already been routed elsewhere.

Do my forward-chain filter rules see the real source address, or the masqueraded one?

The real one. Filter (forward) runs before source NAT, so your accept/drop rules judge the actual client address, not whatever address will replace it on the way out. Source NAT — masquerade — runs afterward, in postrouting; from there on, the outside world sees only the router’s own address, never the host behind it.

What's the difference between mangle prerouting and mangle forward?

Which side of the routing decision they sit on. Mangle prerouting runs before the router has chosen a route, so it's where you mark a connection to steer the routing decision itself — policy routing. Mangle forward runs after the route is already picked, on traffic the router has already committed to sending out a specific interface, which makes it the right place to tag traffic for the queue it's about to hit.

Should I mark the connection or the packet?

Mark the connection when the mark has to follow the whole flow. Connection tracking keeps a connection mark on the connection itself, so a mark set on the first packet applies to every packet after it, in both directions — the mechanism policy routing relies on for the return path. A packet mark lives on one packet: later chains and queues still see it on that packet's way through the router, but the next packet starts clean. The usual pattern uses both — mark the connection once, then set packet or routing marks from the connection mark.

Where do the input and output chains fit into this map?

Off to the side. This diagram is the forward path only — a packet passing through your router. A packet addressed to the router itself branches off right after the routing decision into its own chain: mangle input, then filter input. A packet the router originates runs mangle output and filter output before it ever reaches postrouting. Both are real, documented chains — just not the ones this map draws.

Why can't I reach anything over an IPsec road-warrior tunnel with my normal LAN rules?

Because IPsec traffic has no interface of its own. After decryption it surfaces on the physical interface it arrived on (for a road-warrior, usually your WAN), and a default-deny forward chain drops untrusted WAN traffic as designed. People blame the tunnel first, but the tunnel is fine (field). Keep the WAN closed and accept the decrypted traffic by matching its IPsec policy, ahead of the WAN drop. RouterOS's default firewall ships that accept rule, so the problem shows up in hand-built rulesets.

Why does connection tracking run after RAW instead of before it?

So RAW can act before the router has spent anything on the packet. RAW prerouting is the earliest point where you can act on an arriving packet — it runs before conntrack allocates a tracking entry, which is exactly why a drop there is nearly free. That's the RAW table's stated job: drop or bypass traffic before connection tracking, to spare the CPU. Flip the order and every packet would cost a tracking entry before RAW ever got a chance to say no.

This map also runs on the firewall expertise page. It has a page of its own here so you can send someone a link to the trace alone. Read RouterOS firewall & packet flow — the order I filter by.

Bring me the packet that won’t arrive

Also on the bench: RouterBOARD reset simulator, Visual subnet calculator, Recursive failover simulator, Diffie-Hellman key-exchange visualizer