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.
| 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