Routing Filters in RouterOS: A Complete Guide
Routing Filters in RouterOS: A Complete Guide
Section titled “Routing Filters in RouterOS: A Complete Guide”RouterOS Version: 7.x+ (v7 syntax required) Difficulty: Advanced Estimated Time: 45 minutes
Overview
Section titled “Overview”Routing Filters control route acceptance, rejection, and attribute modification for dynamic routing protocols (BGP, OSPF, RIP). They provide policy control over which routes enter your routing table and what attributes they carry.
Key concepts:
- Filters use script-like
if-then-elsesyntax - Default action is REJECT - unmatched routes are discarded
- Rules are processed top-to-bottom; first match wins
- v7 syntax is completely different from v6
Critical: RouterOS v7 introduced major syntax changes. Filters from v6 or Cisco configurations are NOT compatible and must be rewritten.
Menu Reference
Section titled “Menu Reference”| Menu | Purpose |
|---|---|
/routing/filter/rule | Filter rules for accept/reject/modify |
/routing/filter/select-rule | Selection rules for route candidates |
/routing/filter/num-list | AS number lists for path matching |
/routing/filter/community-list | Standard BGP community lists |
/routing/filter/community-ext-list | Extended BGP community lists |
/routing/filter/community-large-list | Large BGP community lists |
Basic Syntax
Section titled “Basic Syntax”Structure
Section titled “Structure”"if ( [matchers] ) { [actions] } else { [actions] }"Or simple unconditional:
"accept;""reject;"Actions
Section titled “Actions”| Action | Description |
|---|---|
accept | Accept route (stop processing) |
reject | Reject route (stop processing) |
return | Exit to parent chain |
jump [chain] | Branch to another chain |
set [property] [value] | Modify property |
unset [property] | Clear property |
Operators
Section titled “Operators”| Operator | Description |
|---|---|
&& | AND |
|| | OR |
not | Negation |
==, !=, >, <, >=, <= | Comparison |
in | Range or subnet match |
Configuration Examples
Section titled “Configuration Examples”Example 1: Basic BGP Input Filter
Section titled “Example 1: Basic BGP Input Filter”Accept specific prefixes, reject everything else:
# Rule 1: Accept your customer prefixes/routing/filter/rule add chain=bgp-in \ rule="if (dst in 192.168.0.0/16 && dst-len in 16-24) { accept; }"
# Rule 2: Accept default route/routing/filter/rule add chain=bgp-in \ rule="if (dst == 0.0.0.0/0) { accept; }"
# Rule 3: Reject everything else (explicit for clarity)/routing/filter/rule add chain=bgp-in \ rule="reject;"
# Apply to BGP connection/routing/bgp/connection set [find name=upstream] input.filter=bgp-inExample 2: BGP Output Filter with AS Prepend
Section titled “Example 2: BGP Output Filter with AS Prepend”Advertise prefixes with prepending:
# Prepend AS 3 times for backup link/routing/filter/rule add chain=bgp-out-backup \ rule="if (dst in 10.0.0.0/8) { set bgp-path-prepend 3; accept; }"
# Reject all other advertisements/routing/filter/rule add chain=bgp-out-backup \ rule="reject;"
# Apply to BGP connection/routing/bgp/connection set [find name=backup-peer] output.filter-chain=bgp-out-backupExample 3: Set BGP Local Preference
Section titled “Example 3: Set BGP Local Preference”Prefer routes from primary upstream:
# Primary peer - higher local-pref/routing/filter/rule add chain=bgp-in-primary \ rule="set bgp-local-pref 200; accept;"
# Backup peer - lower local-pref/routing/filter/rule add chain=bgp-in-backup \ rule="set bgp-local-pref 100; accept;"
# Apply to connections/routing/bgp/connection set [find name=primary] input.filter=bgp-in-primary/routing/bgp/connection set [find name=backup] input.filter=bgp-in-backupExample 4: Filter by AS Path
Section titled “Example 4: Filter by AS Path”Block routes containing specific AS numbers:
# Create num-list for blocked ASNs/routing/filter/num-list add list=blocked-as range=64496-64511/routing/filter/num-list add list=blocked-as range=65535
# Filter using AS path regex/routing/filter/rule add chain=bgp-in \ rule="if (bgp-as-path .[[:blocked-as:]].) { reject; }"
# Accept everything else/routing/filter/rule add chain=bgp-in \ rule="accept;"Example 5: BGP Community Filtering
Section titled “Example 5: BGP Community Filtering”Handle blackhole communities:
# Create community list/routing/filter/community-list add name=blackhole communities=65535:666
# Check for blackhole community and set route to blackhole/routing/filter/rule add chain=bgp-in \ rule="if (bgp-communities any-list blackhole) { set blackhole yes; accept; }"
# Accept other routes normally/routing/filter/rule add chain=bgp-in \ rule="accept;"Example 6: Add Communities to Outbound Routes
Section titled “Example 6: Add Communities to Outbound Routes”Tag routes with communities:
# Add community to customer routes/routing/filter/rule add chain=bgp-out \ rule="if (dst in 192.168.0.0/16) { append bgp-communities 65000:100; accept; }"
# Accept other routes without modification/routing/filter/rule add chain=bgp-out \ rule="accept;"Example 7: OSPF Redistribution Filter
Section titled “Example 7: OSPF Redistribution Filter”Control which routes are redistributed into OSPF:
# Allow connected routes from specific subnets/routing/filter/rule add chain=ospf-out \ rule="if (protocol connected && dst in 192.168.0.0/16) { set ospf-ext-metric 10; set ospf-ext-type type1; accept; }"
# Allow static routes/routing/filter/rule add chain=ospf-out \ rule="if (protocol static && dst in 10.0.0.0/8) { set ospf-ext-metric 20; set ospf-ext-type type2; accept; }"
# Reject everything else/routing/filter/rule add chain=ospf-out \ rule="reject;"
# Apply to OSPF instance/routing/ospf/instance set [find name=default] out-filter-chain=ospf-outExample 8: Jump to Sub-Chains
Section titled “Example 8: Jump to Sub-Chains”Organize complex filters:
# Bogon check sub-chain/routing/filter/rule add chain=bogon-check \ rule="if (dst in 0.0.0.0/8) { reject; }"/routing/filter/rule add chain=bogon-check \ rule="if (dst in 10.0.0.0/8) { reject; }"/routing/filter/rule add chain=bogon-check \ rule="if (dst in 127.0.0.0/8) { reject; }"/routing/filter/rule add chain=bogon-check \ rule="if (dst in 192.168.0.0/16) { reject; }"/routing/filter/rule add chain=bogon-check \ rule="return;"
# Main filter - jump to bogon check first/routing/filter/rule add chain=bgp-in \ rule="jump bogon-check;"/routing/filter/rule add chain=bgp-in \ rule="accept;"Example 9: Filter Wizard (v7.20+)
Section titled “Example 9: Filter Wizard (v7.20+)”Generate rules using v6-like syntax:
# Generate filter rule/routing/filter filter-wizard action=accept chain=mychain \ prefix=10.0.0.0/8 prefix-length=8-24 set-bgp-local-pref=200
# Result: "if (dst in 10.0.0.0/8 && dst-len in 8-24) { set bgp-local-pref 200; accept; }"AS-PATH Regular Expressions
Section titled “AS-PATH Regular Expressions”RouterOS v7 uses numeric per-ASN matching, different from v6/Cisco string-based patterns.
Syntax
Section titled “Syntax”| Pattern | Description |
|---|---|
^ | Path start (first AS) |
$ | Path end (origin AS) |
. | Any single ASN |
* | Zero or more |
+ | One or more |
? | Zero or one |
| | Alternative |
[123 456] | ASN set |
[^123] | Negated set |
[[:numlist:]] | Reference num-list |
Examples
Section titled “Examples”| Pattern | Matches |
|---|---|
^$ | Empty path (locally originated) |
^1234$ | Single-hop from AS 1234 only |
.1234. | Any path containing AS 1234 |
^1234 | Path starting with AS 1234 |
1234$ | Path ending with AS 1234 (origin) |
^1234+$ | Path with one or more AS 1234 |
Warning: Do NOT copy regex from v6 or Cisco - they use string-based matching!
Matchers Reference
Section titled “Matchers Reference”Prefix Matchers
Section titled “Prefix Matchers”| Matcher | Description |
|---|---|
dst | Destination prefix |
dst-len | Prefix length |
afi | Address family (ipv4, ipv6) |
Protocol Matchers
Section titled “Protocol Matchers”| Matcher | Values |
|---|---|
protocol | bgp, ospf, rip, static, connected |
ospf-type | ext1, ext2, inter, intra, nssa1, nssa2 |
BGP Matchers
Section titled “BGP Matchers”| Matcher | Description |
|---|---|
bgp-as-path | AS path regex |
bgp-path-len | AS path length |
bgp-communities | Community matching |
bgp-network | Originated via network statement |
Writable Properties
Section titled “Writable Properties”BGP Attributes
Section titled “BGP Attributes”| Property | Description |
|---|---|
bgp-local-pref | Local preference |
bgp-med | Multi-Exit Discriminator |
bgp-path-prepend | AS prepend count |
bgp-origin | Origin (igp, egp, incomplete) |
bgp-weight | Weight |
OSPF Attributes
Section titled “OSPF Attributes”| Property | Description |
|---|---|
ospf-ext-metric | External metric |
ospf-ext-type | External type (type1, type2) |
ospf-ext-tag | External tag |
General
Section titled “General”| Property | Description |
|---|---|
distance | Administrative distance |
blackhole | Make blackhole route |
pref-src | Preferred source |
gw | Gateway |
Common Problems and Solutions
Section titled “Common Problems and Solutions”Problem 1: All Routes Rejected
Section titled “Problem 1: All Routes Rejected”Cause: Default action is reject; missing accept statement.
Solution: Always add explicit accept for wanted routes:
# Your conditional rules here...# End with accept for remaining routes/routing/filter/rule add chain=bgp-in rule="accept;"Problem 2: v6 Filters Don’t Work in v7
Section titled “Problem 2: v6 Filters Don’t Work in v7”Cause: Completely different syntax.
v6 syntax (doesn’t work):
/routing filter add action=accept chain=bgp-in prefix=10.0.0.0/8v7 syntax (correct):
/routing/filter/rule add chain=bgp-in rule="if (dst in 10.0.0.0/8) { accept; }"Problem 3: AS-PATH Regex Doesn’t Match
Section titled “Problem 3: AS-PATH Regex Doesn’t Match”Cause: v7 uses numeric per-ASN matching, not string matching.
Wrong (string-based):
rule="if (bgp-as-path \"_1234_\") { reject; }"Correct (numeric):
rule="if (bgp-as-path .1234.) { reject; }"Problem 4: Filter Not Taking Effect
Section titled “Problem 4: Filter Not Taking Effect”Cause: Filter chain not applied to protocol.
Solution:
# For BGP/routing/bgp/connection set [find name=peer1] input.filter=bgp-in
# For OSPF/routing/ospf/instance set [find] out-filter-chain=ospf-outProblem 5: Cannot Filter OSPF Internal Routes
Section titled “Problem 5: Cannot Filter OSPF Internal Routes”Cause: OSPF is link-state; filters only work on external routes.
Workaround:
- Use area summarization on ABR
- Convert area to NSSA with no-summary
- Filter at redistribution point, not OSPF-to-OSPF
Problem 6: Prefix Match Too Restrictive
Section titled “Problem 6: Prefix Match Too Restrictive”Problem: dst in 10.0.0.0/8 only matches that exact prefix.
Solution: Add prefix length condition:
# Match all prefixes within 10.0.0.0/8rule="if (dst in 10.0.0.0/8 && dst-len >= 8) { accept; }"
# Match specific length rangerule="if (dst in 10.0.0.0/8 && dst-len in 16-24) { accept; }"v6 to v7 Migration Quick Reference
Section titled “v6 to v7 Migration Quick Reference”| v6 | v7 |
|---|---|
prefix=10.0.0.0/8 | dst in 10.0.0.0/8 |
prefix-length=16-24 | dst-len in 16-24 |
action=accept | accept; |
action=discard | reject; |
set-bgp-prepend=3 | set bgp-path-prepend 3; |
bgp-as-path=".1234." | bgp-as-path .1234. |
jump-target=chain2 | jump chain2; |
Verification Commands
Section titled “Verification Commands”# View all filter rules/routing/filter/rule print
# View specific chain/routing/filter/rule print where chain=bgp-in
# Check BGP connection filter assignment/routing/bgp/connection print detail
# View filtered (rejected) routes/routing/route print where filtered
# Check community lists/routing/filter/community-list print
# Check num-lists/routing/filter/num-list printRelated Features
Section titled “Related Features”- BGP (
/routing/bgp) - Primary filter consumer - OSPF (
/routing/ospf) - Uses filters for redistribution - RIP (
/routing/rip) - Uses filters for route control - RPKI (
/routing/rpki) - Integrates with filters for validation - Routing Tables (
/routing/table) - Filters can reference tables
Summary
Section titled “Summary”Routing Filters in RouterOS v7 use script-like syntax for route policy:
- Create filter rules with
if-then-elsesyntax - Apply to protocol via
input.filteroroutput.filter-chain - Always add explicit accept for wanted routes
Key points:
- Default action is REJECT
- v7 syntax is completely different from v6
- AS-PATH uses numeric regex, not string-based
- OSPF internal routes cannot be filtered
- Use Filter Wizard (v7.20+) for easier migration
Related Topics
Section titled “Related Topics”Prerequisites
Section titled “Prerequisites”- Static Routes - understand basic routing concepts
Routing Protocols Using Filters
Section titled “Routing Protocols Using Filters”- BGP Basic Peering - primary use case for routing filters
- OSPF Configuration - filter external route redistribution
- Routing Rules - policy-based routing (different from filters)
Related Topics
Section titled “Related Topics”- Firewall Mangle - traffic marking for policy routing
- IP Address Configuration - address ranges for filter matching