VyOSXXXIII · Route PolicyPolicy primitives
Policy concept — the vocabulary, the building blocks, the evaluation order
What you'll learn
- Name the five policy primitives and explain the role of each
- Walk the evaluation order from a single route through prefix-list, as-path-list, community-list, route-map
- Distinguish implicit deny (list end) from explicit deny (rule with action deny)
- Recognise the production failure mode where a route silently bypasses the policy
Prerequisites
Verified against VyOS 1.5.x LTS (circinus) · VyOS 1.4.x (sagitta) — legacy · FRRouting 10.x (VyOS 1.5) · Linux kernel 6.6 LTS (VyOS 1.5 base) · strongSwan 5.9.x (IPsec) · WireGuard 1.0.x (kernel module + userspace tooling) · 2026-08-15
Routing policy is the bridge between what the routing protocol learned and what the operator is willing to advertise, accept, or manipulate. On VyOS 1.5 LTS the policy tree is a small set of ordered, sequential primitives; the operator who understands the primitives can build filters that are explicit, auditable, and safe under change. The operator who treats policy as a black box will eventually leak a prefix into BGP or drop a transit route during an outage.
This lesson introduces the vocabulary and the evaluation order. The following five lessons dig into each primitive individually.
The five policy primitives
A VyOS 1.5 LTS routing policy is composed of five primitives:
- prefix-list — a list of IPv4 or IPv6 prefix entries with
action permitoraction deny, evaluated top-to-bottom by sequence number, withge(greater-than-or-equal prefix length),le(less-than-or-equal prefix length), and exact-match variants. Matches a route’s prefix AND its prefix length. - community-list — a list of BGP community entries. Standard community-lists match exact communities; expanded community lists match regular expressions. Used to filter or stamp routes by their BGP community.
- as-path-list — a list of BGP AS-path regular expressions. Used to filter or match routes by the AS sequence in the path attribute.
- route-map — an ordered, named list of rules. Each rule
has a sequence number, an action (
permitordeny), amatchclause (which list to consult), and asetclause (which attributes to write back to the route). - sequence — the numeric ordering of rules inside a primitive. Rules evaluate in ascending sequence order. The first rule that matches the route decides the disposition; later rules are not consulted.
The vocabulary is small but the combination is expressive. A route-map can match a prefix-list and a community-list on the same rule; the rule fires only when both lists permit.
flowchart TB
R["Inbound route\nfrom peer or redistribution"]
PL["prefix-list\n(top-to-bottom by sequence)\nmatch: prefix + prefix-length"]
CL["community-list\n(top-to-bottom by sequence)\nmatch: standard or expanded regex"]
APL["as-path-list\n(top-to-bottom by sequence)\nmatch: regex over AS_PATH"]
RM["route-map\n(top-to-bottom by sequence)\nmatch + set clauses"]
D{"Decision"}
P["Permit: route continues;\nset clauses applied"]
X["Deny: route is filtered"]
R --> PL
PL -->|"no match (implicit deny)"| X
PL -->|"explicit deny"| X
PL -->|"permit"| CL
CL -->|"no match"| X
CL -->|"explicit deny"| X
CL -->|"permit"| APL
APL -->|"no match"| X
APL -->|"explicit deny"| X
APL -->|"permit"| RM
RM --> D
D -->|"rule action permit"| P
D -->|"rule action deny"| X
The diagram is the production mental model. A route walks
prefix-list first, then community-list, then as-path-list, then
route-map. Each list evaluates top-to-bottom. If any list
returns “no match” (the implicit deny at the end of every
list), the route is filtered before the next primitive is
consulted. The route-map is the only primitive that can write
back to the route (set clauses).
Sequence semantics — why order matters
Every primitive is ordered and sequential. Two rules in the same list cannot match the same route; the first rule by sequence wins.
# VyOS 1.5 LTS sequence-numbered policy
set policy prefix-list CUSTOMERS rule 10 action permit
set policy prefix-list CUSTOMERS rule 10 prefix 10.0.0.0/8 le 16
set policy prefix-list CUSTOMERS rule 20 action permit
set policy prefix-list CUSTOMERS rule 20 prefix 192.168.0.0/16 le 24
set policy prefix-list CUSTOMERS rule 30 action deny
The list is read top-to-bottom. A route for 10.5.0.0/16 is
matched by rule 10 (the prefix and the prefix-length fit the
/8 le 16). Rule 20 is never consulted. The route is
permitted.
A route for 172.16.0.0/12 does not match rule 10 (different
prefix) and does not match rule 20 (different prefix). Rule 30
explicitly denies it. The route is denied.
A route for 203.0.113.0/24 matches no rule. The list falls
off the end. The implicit deny applies. The route is denied.
Implicit deny vs explicit deny
The implicit deny (the end of every list) is different from
an explicit deny (a rule with action deny).
| Concept | Mechanism | Effect |
|---|---|---|
| Implicit deny | End of every list | If no rule matched, deny |
| Explicit deny | set policy <list> rule N action deny | If this rule matched, deny |
The explicit deny is a shortcut. It tells the policy engine: “anything that matches this rule is denied, no need to walk the rest of the list”. Without the explicit deny, the operator must rely on the implicit deny to catch the remaining prefixes.
A common production idiom is to end every list with a catch-all deny:
# Allow specific prefixes, deny everything else
set policy prefix-list INBOUND rule 10 action permit
set policy prefix-list INBOUND rule 10 prefix 192.168.1.0/24
set policy prefix-list INBOUND rule 20 action permit
set policy prefix-list INBOUND rule 20 prefix 192.168.2.0/24
set policy prefix-list INBOUND rule 1000 action deny
The explicit deny at rule 1000 is redundant — the implicit deny at the end of the list would deny the route anyway. The explicit deny makes the intent visible in the configuration and survives a future “I added rule 30, did I break anything?” review.
Where policy is applied
A policy primitive is inert on its own. It must be referenced by a route-map or directly by a protocol:
- prefix-list is referenced from a route-map
match ip address prefix-list <name>clause. The route-map is then applied to BGP neighbours (inbound or outbound) or to a redistribution. - community-list is referenced from a route-map
match community <name>clause. - as-path-list is referenced from a route-map
match as-path <name>clause. - route-map is referenced from a BGP neighbour (inbound or outbound filter) or from a redistribution statement.
A standalone prefix-list does nothing. A standalone community-list does nothing. The route-map is the only primitive that can combine matches and produce an effect on a route.
Operational commands
The operator verifies the policy state with:
# All configured policies
show policy route-map
show policy prefix-list
show policy community-list
show policy as-path-list
# The matching engine's view (FRR)
vtysh -c 'show ip prefix-list'
vtysh -c 'show bgp community-list'
vtysh -c 'show bgp as-path-access-list'
# The result against a specific prefix
vtysh -c 'show ip prefix-list INBOUND 192.168.1.0/24'
# The route-map applied to a neighbour
vtysh -c 'show ip bgp neighbors 10.0.0.2 routes'
The show policy ... commands read the VyOS configuration tree.
The vtysh -c 'show ...' commands read the live FRR state.
Both should agree; if they do not, a commit is in progress or
has failed silently.
Rollback
Every policy change in this course has a tested rollback path:
rollback Nandcommitto revert to a previous configuration revision (VyOS keeps numbered revisions in/config/config.bootand/config/archive/).delete policy prefix-list <name>andcommitto remove a list that is no longer referenced.discardto throw away the candidate configuration before the commit.- A saved backup file (
load <file>) to replace the candidate when the rollback is structural. - Out-of-band console for when the configuration being rolled back is the access path.
The VyOS commit engine validates policy at commit time. A policy that references a missing prefix-list is rejected. A policy that references a deleted list is left dangling. The operator must verify the commit succeeded and the policy is still referenced from the route-map.
Production discipline
The operator who follows these rules writes policy that is correct on first commit and stays correct under change. The operator who skips them writes policy that works in the lab and leaks in production.
Cross-course references
- Part XXVI (
XXVI-VyOS-BGPAttributes) covers AS_PATH and community as BGP path attributes. The policy primitives here match against those attributes. - Part XXVIII (
XXVIII-VyOS-BGPPrefixFilters) covers prefix-list and prefix-filter at depth. The vocabulary overlaps with this lesson’s prefix-list section. - Part XXXIV (
XXXIV-VyOS-Redistribution) uses route-maps to filter redistributed routes. The route-map is the bridge between the policy tree and the redistribution.
Quiz
Knowledge check · 4 questions
Q1. A route enters a prefix-list with three permit rules and no explicit deny. The route matches no rule. What is the disposition?
Q2. Two rules in the same prefix-list can match the same route; the more specific rule wins.
Q3. An operator configures a prefix-list with rule 10 permitting 10.0.0.0/8 le 16, rule 20 permitting 10.5.0.0/16, and rule 1000 denying. A route for 10.5.0.0/16 arrives. Which rule fires and what is the disposition?
The list is: rule 10 (10.0.0.0/8 le 16 permit), rule 20 (10.5.0.0/16 permit), rule 1000 (deny). The route 10.5.0.0/16 is evaluated.
Q4. An operator builds a community-list with rule 10 permitting 64512:100 and rule 20 permitting 64512:200. The list is referenced from a route-map on the inbound side of a BGP peer. A route arrives with community 64512:300. What happens?
The route-map has `match community FROM-PEER-A`. The community-list FROM-PEER-A has rule 10 (permit 64512:100) and rule 20 (permit 64512:200). No explicit deny. The route carries 64512:300.
Passing score: 75%. Answers are checked in this browser.