MikroTik RouterOS Firewall Mangle: Packet Marking and Traffic Classification
MikroTik RouterOS Firewall Mangle: Packet Marking and Traffic Classification
Section titled âMikroTik RouterOS Firewall Mangle: Packet Marking and Traffic ClassificationâTL;DR (Quick Start)
Section titled âTL;DR (Quick Start)âFor the impatient: hereâs the 30-second version.
# Mark web traffic connections and packets for QoS/ip firewall mangle add chain=forward connection-state=new protocol=tcp dst-port=80,443 action=mark-connection new-connection-mark=web_conn/ip firewall mangle add chain=forward connection-mark=web_conn action=mark-packet new-packet-mark=web_pkt passthrough=noOverview
Section titled âOverviewâThe firewall mangle is RouterOSâs traffic classification engine - it marks packets, connections, and routes for processing by other facilities like queues, NAT, and routing tables. Unlike the firewall filter (which allows or blocks traffic), mangle identifies and categorizes traffic without affecting whether it passes or not.
Understanding mangle is essential because:
- QoS depends on it: Queue trees use packet marks to apply bandwidth policies
- Policy routing needs it: Route marks direct traffic through specific gateways
- Traffic shaping requires it: Connection marks enable per-client bandwidth management
- Advanced NAT uses it: Marked connections can be treated differently by NAT rules
This guide explains how mangle fits into the packet processing pipeline, the three types of marks, and practical patterns for traffic classification.
The Mangle Processing Pipeline
Section titled âThe Mangle Processing PipelineâMangle operates at specific points in the packet flow. Understanding where each chain processes packets is critical for effective traffic marking:
âââââââââââââââ â INPUT â â chain ââââ Local Process âââââââââââââââ âInternet âââ [PREROUTING] âââ [Routing] ââ⤠chain Decision â â âââââââââââââââ â FORWARD â â chain â âââââââââââââââ â âLocal Process âââ [OUTPUT] âââ [Routing] âââ [POSTROUTING] âââ Internet chain Decision chainKey insight: PREROUTING runs before the routing decision, making it ideal for policy routing marks. FORWARD only processes transit traffic, making it efficient for QoS marking of client traffic.
The Five Mangle Chains
Section titled âThe Five Mangle ChainsâRouterOS has five predefined mangle chains that cannot be deleted. Each processes packets at a specific point:
PREROUTING Chain: First Contact
Section titled âPREROUTING Chain: First ContactâWhen: Immediately after packet arrives on interface, before routing decision.
Use cases:
- Policy routing (mark-routing)
- Early traffic classification
- Marking traffic before it splits into INPUT or FORWARD
Example: Mark all traffic from a specific VLAN for a separate routing table:
/ip firewall mangle add chain=prerouting in-interface=vlan100 action=mark-routing new-routing-mark=isp2INPUT Chain: Traffic to the Router
Section titled âINPUT Chain: Traffic to the RouterâWhen: After routing decision, for packets destined to the router itself.
Use cases:
- Mark management traffic for QoS
- Classify services running on the router
- Monitor traffic to router services
Example: Mark DNS queries to the router:
/ip firewall mangle add chain=input protocol=udp dst-port=53 action=mark-packet new-packet-mark=dns_queriesFORWARD Chain: Transit Traffic
Section titled âFORWARD Chain: Transit TrafficâWhen: After routing decision, for packets passing through the router.
Use cases:
- QoS packet marking for client traffic
- Connection marking for bandwidth management
- Traffic classification between networks
Example: Mark HTTP traffic for queue tree:
/ip firewall mangle add chain=forward protocol=tcp dst-port=80 action=mark-packet new-packet-mark=http_trafficOUTPUT Chain: Router-Generated Traffic
Section titled âOUTPUT Chain: Router-Generated TrafficâWhen: After local process generates packet, before routing decision.
Use cases:
- Mark router-generated traffic for policy routing
- Classify traffic from router services
- QoS for routerâs own traffic
Example: Mark routerâs backup traffic:
/ip firewall mangle add chain=output protocol=tcp dst-port=21 action=mark-routing new-routing-mark=backup_linkPOSTROUTING Chain: Final Processing
Section titled âPOSTROUTING Chain: Final ProcessingâWhen: Just before packet leaves the router, after all routing decisions.
Use cases:
- Final packet modifications (DSCP, TTL)
- Marking after NAT has been applied
- Last chance to classify outbound traffic
Example: Set DSCP for all outbound VoIP traffic:
/ip firewall mangle add chain=postrouting protocol=udp dst-port=5060 action=change-dscp new-dscp=46Understanding Mark Types
Section titled âUnderstanding Mark TypesâMangle creates three distinct types of marks, each serving different purposes:
Packet Marks: Per-Packet Classification
Section titled âPacket Marks: Per-Packet ClassificationâScope: Individual packet only Persistence: Transient - exists only while packet is processed Primary use: Queue trees for bandwidth management
/ip firewall mangle add chain=forward protocol=tcp dst-port=80 action=mark-packet new-packet-mark=web_trafficHow queues use packet marks:
/queue tree add name=web_queue parent=global packet-mark=web_traffic max-limit=10MImportant: Packet marks are router-internal only. They are not transmitted across the network and cannot be seen by other devices.
Connection Marks: Efficient Classification
Section titled âConnection Marks: Efficient ClassificationâScope: All packets in a connection Persistence: Stored in connection tracking table Primary use: Reduce CPU by marking once, matching many
The connection marking pattern is essential for performance:
# Rule 1: Mark new connections (inspects headers once)/ip firewall mangle add chain=forward connection-state=new src-address=192.168.88.0/24 \ action=mark-connection new-connection-mark=lan_conn
# Rule 2: Mark packets based on connection mark (fast lookup)/ip firewall mangle add chain=forward connection-mark=lan_conn \ action=mark-packet new-packet-mark=lan_trafficWhy this matters: Without connection marks, every packet requires header inspection. With connection marks, only the first packet of each connection is fully analyzed - subsequent packets use a fast connection table lookup.
Routing Marks: Policy Routing
Section titled âRouting Marks: Policy RoutingâScope: Packetâs routing decision Persistence: Until routing decision is made Primary use: Direct traffic through specific routing tables
# RouterOS v7: Create routing table first (required)/routing table add name=via_isp2 fib
# Mark traffic for secondary ISP (exclude local traffic!)/ip firewall mangle add chain=prerouting src-address=192.168.100.0/24 \ dst-address-type=!local action=mark-routing new-routing-mark=via_isp2
# Route marked traffic through ISP2/ip route add dst-address=0.0.0.0/0 gateway=10.0.0.1 routing-table=via_isp2Critical notes:
- RouterOS v7 requires pre-created routing tables: Create with
/routing table add name=myTable fibbefore usingmark-routing - Always exclude local traffic: Use
dst-address-type=!localto prevent breaking routerâs own connectivity - FastTrack incompatible: Traffic with routing marks cannot use FastTrack
The Passthrough Parameter
Section titled âThe Passthrough ParameterâThe passthrough parameter controls whether rule processing continues after a match:
passthrough=yes (default): Continue to next rule after action passthrough=no: Stop processing after action
When to Use passthrough=yes
Section titled âWhen to Use passthrough=yesâUse when you need multiple marks on the same packet:
# Mark connection first (passthrough=yes by default)/ip firewall mangle add chain=forward connection-state=new src-address=192.168.88.0/24 \ action=mark-connection new-connection-mark=internal_conn
# Then mark packet (same packet, second mark)/ip firewall mangle add chain=forward connection-mark=internal_conn \ action=mark-packet new-packet-mark=internal_pkt passthrough=noWhen to Use passthrough=no
Section titled âWhen to Use passthrough=noâUse when the mark is final and no further processing is needed:
# Final classification - stop processing/ip firewall mangle add chain=forward protocol=tcp dst-port=22 \ action=mark-packet new-packet-mark=ssh_traffic passthrough=noPerformance tip: Use passthrough=no on your final rules to avoid unnecessary rule traversal.
Mangle Actions Reference
Section titled âMangle Actions Referenceâ| Action | Description | Use Case |
|---|---|---|
mark-packet | Add packet mark | Queue tree classification |
mark-connection | Add connection mark | Efficient per-connection classification |
mark-routing | Add routing mark | Policy-based routing |
change-dscp | Modify DSCP field (0-63) | QoS marking for upstream devices |
change-ttl | Modify TTL value | Prevent traceroute, hide hops |
change-mss | Modify Maximum Segment Size | Fix path MTU discovery issues |
set-priority | Set VLAN/WMM priority | Layer 2 QoS |
clear-df | Remove Donât Fragment flag | Allow fragmentation |
sniff-tzsp | Export to TZSP receiver | Packet capture to Wireshark |
Configuration Steps
Section titled âConfiguration StepsâThis section provides a practical configuration that demonstrates the core mangle concepts.
Step 1: Create Connection Marks for Traffic Classification
Section titled âStep 1: Create Connection Marks for Traffic ClassificationâMark connections by traffic type for efficient processing:
/ip firewall mangleadd chain=forward connection-state=new protocol=tcp dst-port=80,443 \ action=mark-connection new-connection-mark=web_conn comment="Mark web connections"add chain=forward connection-state=new protocol=udp dst-port=53 \ action=mark-connection new-connection-mark=dns_conn comment="Mark DNS connections"add chain=forward connection-state=new protocol=tcp dst-port=22 \ action=mark-connection new-connection-mark=ssh_conn comment="Mark SSH connections"Step 2: Create Packet Marks from Connection Marks
Section titled âStep 2: Create Packet Marks from Connection MarksâConvert connection marks to packet marks for queue trees:
/ip firewall mangleadd chain=forward connection-mark=web_conn action=mark-packet \ new-packet-mark=web_pkt passthrough=no comment="Web packet mark"add chain=forward connection-mark=dns_conn action=mark-packet \ new-packet-mark=dns_pkt passthrough=no comment="DNS packet mark"add chain=forward connection-mark=ssh_conn action=mark-packet \ new-packet-mark=ssh_pkt passthrough=no comment="SSH packet mark"Step 3: Use Packet Marks in Queue Tree (Optional)
Section titled âStep 3: Use Packet Marks in Queue Tree (Optional)âApply bandwidth policies based on marks:
/queue treeadd name=download parent=global max-limit=100Madd name=web_download parent=download packet-mark=web_pkt max-limit=50Madd name=dns_download parent=download packet-mark=dns_pkt max-limit=5M priority=1add name=ssh_download parent=download packet-mark=ssh_pkt max-limit=10M priority=2Verification
Section titled âVerificationâConfirm your mangle rules are active and processing traffic.
Check 1: Verify Rules Are Created
Section titled âCheck 1: Verify Rules Are Createdâ/ip firewall mangle printExpected Output:
Flags: X - disabled, I - invalid, D - dynamic # CHAIN ACTION CONNECTION-MARK NEW-CONN-MARK NEW-PKT-MARK 0 forward mark-connection web_conn 1 forward mark-connection dns_conn 2 forward mark-connection ssh_conn 3 forward mark-packet web_conn web_pkt 4 forward mark-packet dns_conn dns_pkt 5 forward mark-packet ssh_conn ssh_pktCheck 2: Monitor Rule Statistics
Section titled âCheck 2: Monitor Rule Statisticsâ/ip firewall mangle print statsExpected Output:
# CHAIN ACTION BYTES PACKETS 0 forward mark-connection 0 0 1 forward mark-connection 0 0 2 forward mark-connection 0 0 3 forward mark-packet 1,234,567 8,901 4 forward mark-packet 45,678 234 5 forward mark-packet 98,765 543Check 3: Verify Connection Marks in Tracking Table
Section titled âCheck 3: Verify Connection Marks in Tracking Tableâ/ip firewall connection print where connection-mark!=""Expected Output:
# PROTOCOL SRC-ADDRESS DST-ADDRESS CONNECTION-MARK 0 tcp 192.168.88.10:4521 93.184.216.34:443 web_conn 1 udp 192.168.88.10:5353 8.8.8.8:53 dns_connCommon Patterns
Section titled âCommon PatternsâPattern 1: Per-Client Bandwidth Management
Section titled âPattern 1: Per-Client Bandwidth ManagementâMark each clientâs traffic separately for individual queue limits:
# Mark connections per client/ip firewall mangleadd chain=forward connection-state=new src-address=192.168.88.10 \ action=mark-connection new-connection-mark=client10_connadd chain=forward connection-state=new src-address=192.168.88.11 \ action=mark-connection new-connection-mark=client11_conn
# Mark packets for queuingadd chain=forward connection-mark=client10_conn action=mark-packet \ new-packet-mark=client10_pkt passthrough=noadd chain=forward connection-mark=client11_conn action=mark-packet \ new-packet-mark=client11_pkt passthrough=noPattern 2: Dual-WAN Load Balancing
Section titled âPattern 2: Dual-WAN Load BalancingâMark traffic for different ISPs based on source:
# Mark traffic from different subnets for different ISPs/ip firewall mangleadd chain=prerouting src-address=192.168.10.0/24 action=mark-routing \ new-routing-mark=to_isp1add chain=prerouting src-address=192.168.20.0/24 action=mark-routing \ new-routing-mark=to_isp2
# Create routing table entries/ip routeadd dst-address=0.0.0.0/0 gateway=10.0.1.1 routing-mark=to_isp1add dst-address=0.0.0.0/0 gateway=10.0.2.1 routing-mark=to_isp2Pattern 3: MSS Clamping for PPPoE/VPN
Section titled âPattern 3: MSS Clamping for PPPoE/VPNâFix path MTU discovery issues by clamping TCP MSS for tunneled connections:
# Clamp MSS for outbound traffic through PPPoE/ip firewall mangle add chain=forward protocol=tcp tcp-flags=syn \ out-interface=pppoe-out tcp-mss=1301-65535 action=change-mss new-mss=1300 \ passthrough=yes comment="Clamp MSS for PPPoE outbound"
# Clamp MSS for inbound traffic through PPPoE/ip firewall mangle add chain=forward protocol=tcp tcp-flags=syn \ in-interface=pppoe-out tcp-mss=1301-65535 action=change-mss new-mss=1300 \ passthrough=yes comment="Clamp MSS for PPPoE inbound"Why this works: PPPoE adds 8 bytes of overhead, reducing effective MTU. When PMTUD fails (ICMP blocked), TCP connections stall with large packets. MSS clamping forces smaller TCP segments, avoiding fragmentation issues.
Pattern 4: DSCP Marking for Upstream QoS
Section titled âPattern 4: DSCP Marking for Upstream QoSâSet DSCP values for traffic that will be prioritized by upstream devices:
/ip firewall mangleadd chain=postrouting protocol=udp dst-port=5060-5061 action=change-dscp \ new-dscp=46 comment="VoIP signaling - EF"add chain=postrouting protocol=udp dst-port=10000-20000 action=change-dscp \ new-dscp=46 comment="VoIP RTP - EF"add chain=postrouting protocol=tcp dst-port=22 action=change-dscp \ new-dscp=26 comment="SSH - AF31"Pattern 5: Bypass FastTrack for Marked Traffic
Section titled âPattern 5: Bypass FastTrack for Marked TrafficâWhen using policy routing, ensure marked traffic bypasses FastTrack:
# FastTrack unmarked traffic only/ip firewall filteradd chain=forward connection-state=established,related routing-mark="" \ action=fasttrack-connectionadd chain=forward connection-state=established,related action=acceptTroubleshooting
Section titled âTroubleshootingâProblem: âMangle rules show zero packet countsâ
Section titled âProblem: âMangle rules show zero packet countsââCause: Rules may be unreachable, or traffic doesnât match criteria.
Solution:
- Check rule order - earlier rules may match first with
passthrough=no - Verify traffic exists:
/ip firewall connection print - Check chain selection - use
forwardfor transit traffic, notinput - Ensure connection tracking is enabled:
/ip firewall connection tracking print
Problem: âConnection marks not appearing in connection tableâ
Section titled âProblem: âConnection marks not appearing in connection tableââCause: Rule may be in wrong chain or connection-state not specified.
Solution:
- For new connection marks, use
connection-state=new - Use
preroutingorforwardchain, notpostrouting - Verify rule matches: add
log=yestemporarily to debug
Problem: âPolicy routing marks donât affect trafficâ
Section titled âProblem: âPolicy routing marks donât affect trafficââCause: Routing table or routes may be misconfigured.
Solution:
- Verify routing mark is set in
preroutingchain (before routing decision) - Check route exists with matching routing-mark:
/ip route print where routing-mark=your_mark - Ensure FastTrack isnât processing marked connections
- Verify with:
/ip firewall mangle print stats
Problem: âPacket mark limit exceededâ error
Section titled âProblem: âPacket mark limit exceededâ errorâCause: RouterOS has a limit of 4096 unique packet marks.
Solution:
- Use connection marks instead of packet marks where possible
- Consolidate similar traffic under fewer marks
- Review if all marks are necessary
- Check for dynamic mark generation that may be creating excessive marks
Problem: âQueue tree doesnât apply to marked trafficâ
Section titled âProblem: âQueue tree doesnât apply to marked trafficââCause: Packet marks may not match queue configuration.
Solution:
- Verify exact packet mark name in both mangle and queue
- Check queue tree parent interface matches traffic path
- Ensure
passthrough=noon final packet mark rule - Verify marks are created:
/ip firewall mangle print stats
Performance Considerations
Section titled âPerformance ConsiderationsâUse Connection Marks for Efficiency
Section titled âUse Connection Marks for EfficiencyâWrong approach (CPU intensive):
# Every packet inspected/ip firewall mangle add chain=forward src-address=192.168.88.0/24 \ action=mark-packet new-packet-mark=lan_pktRight approach (efficient):
# First packet inspected, connection marked/ip firewall mangle add chain=forward connection-state=new src-address=192.168.88.0/24 \ action=mark-connection new-connection-mark=lan_conn# Subsequent packets use fast connection lookup/ip firewall mangle add chain=forward connection-mark=lan_conn \ action=mark-packet new-packet-mark=lan_pktRule Order Matters
Section titled âRule Order Mattersâ- Place most frequently matched rules at the top
- Use
passthrough=nowhen no further matching is needed - Mark connections first, then derive packet marks
- Group related rules together to improve cache efficiency
FastTrack Interaction
Section titled âFastTrack InteractionâFastTrack bypasses firewall processing for marked connections. This is incompatible with:
- Policy routing (routing marks)
- Queue trees requiring packet marks
- Any mangle processing of established connections
To use mangle with FastTrack, exclude marked traffic:
/ip firewall filter add chain=forward connection-state=established,related \ connection-mark="" action=fasttrack-connectionCommon Mistakes
Section titled âCommon MistakesâMistake 1: Using Wrong Chain
Section titled âMistake 1: Using Wrong ChainâWrong: Marking transit traffic in INPUT chain
# INPUT is for traffic TO the router, not through it/ip firewall mangle add chain=input src-address=192.168.88.0/24 action=mark-packet new-packet-mark=client_pktRight: Use FORWARD for transit traffic
/ip firewall mangle add chain=forward src-address=192.168.88.0/24 action=mark-packet new-packet-mark=client_pktMistake 2: Routing Marks in Wrong Chain
Section titled âMistake 2: Routing Marks in Wrong ChainâWrong: Setting routing mark after routing decision
# Routing decision already made - mark has no effect/ip firewall mangle add chain=forward action=mark-routing new-routing-mark=isp2Right: Set routing marks in PREROUTING
# Before routing decision - mark affects route selection/ip firewall mangle add chain=prerouting action=mark-routing new-routing-mark=isp2Mistake 3: Forgetting passthrough=no
Section titled âMistake 3: Forgetting passthrough=noâProblem: Packet gets marked multiple times, wasting CPU
# All rules process because passthrough=yes (default)/ip firewall mangle add chain=forward protocol=tcp dst-port=80 action=mark-packet new-packet-mark=web/ip firewall mangle add chain=forward protocol=tcp dst-port=443 action=mark-packet new-packet-mark=https/ip firewall mangle add chain=forward action=mark-packet new-packet-mark=otherSolution: Add passthrough=no to terminal rules
/ip firewall mangle add chain=forward protocol=tcp dst-port=80 action=mark-packet new-packet-mark=web passthrough=no/ip firewall mangle add chain=forward protocol=tcp dst-port=443 action=mark-packet new-packet-mark=https passthrough=no/ip firewall mangle add chain=forward action=mark-packet new-packet-mark=other passthrough=noMistake 4: Not Using Connection Marks
Section titled âMistake 4: Not Using Connection MarksâInefficient: Inspecting every packet
/ip firewall mangle add chain=forward src-address=192.168.88.100 action=mark-packet new-packet-mark=client100Efficient: Mark connection once, then match connection mark
/ip firewall mangle add chain=forward connection-state=new src-address=192.168.88.100 \ action=mark-connection new-connection-mark=client100_conn/ip firewall mangle add chain=forward connection-mark=client100_conn \ action=mark-packet new-packet-mark=client100Related Topics
Section titled âRelated TopicsâPrerequisites
Section titled âPrerequisitesâ- IP Address Configuration - interface addressing fundamentals
- Static Routes - routing concepts for policy routing
Related Firewall Topics
Section titled âRelated Firewall Topicsâ- Firewall Filter Basics - packet filtering (complementary to mangle)
- NAT Masquerade - NAT works with mangle marks
- Address Lists - address groups for mangle matching
Uses Mangle Marks
Section titled âUses Mangle Marksâ- Simple Queues - bandwidth limiting
- Queue Tree - advanced QoS using packet marks
Multi-WAN
Section titled âMulti-WANâ- DHCP Client - multi-WAN with mangle-based load balancing