Skip to main content
RunBook Academy

VyOSXXXIII · Route PolicyPrefix-list

Prefix-list — sequence, ge, le, exact-match, deny vs permit

Advanced⏱ ~24 minvyosvtyshset policy prefix-listshow policy prefix-listvtysh -c show ip prefix-listvtysh -c show ip prefix-list <name> <prefix>clear ip prefix-list

What you'll learn

  • Configure a prefix-list with sequence, ge, le, and exact-match on VyOS 1.5 LTS
  • Predict which prefixes a ge or le combination will match
  • Distinguish prefix-list matching from access-list matching
  • Diagnose over-broad and under-specified prefix-lists in production

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

Not yet marked complete on this device.

The prefix-list is the workhorse of VyOS 1.5 LTS routing policy. It filters IPv4 and IPv6 prefixes by both the network and the prefix-length, and it is the canonical filter for BGP neighbour policies, redistribution route-maps, and any other match-against-prefix context the operator needs.

A correctly written prefix-list is small, ordered, and auditable. An incorrectly written one is the most common source of route leaks and dropped traffic in production. This lesson covers the four operators (exact-match, ge, le, ge+le), the sequence semantics, and the failure modes the operator will encounter.

The four operators

A prefix-list rule has three relevant attributes:

  • prefix — the IPv4 or IPv6 network (e.g. 10.0.0.0/8).
  • actionpermit or deny.
  • length operatorsge, le, or neither.

The four combinations are:

  • exact-match (no operator) — the route’s prefix must match exactly and the prefix length must equal the rule’s prefix length. 10.0.0.0/8 matches only 10.0.0.0/8.
  • ge (greater-than-or-equal) — the route’s prefix must be within the rule’s prefix, and the route’s prefix length must be greater-than-or-equal to the ge value. 10.0.0.0/8 ge 16 matches 10.0.0.0/16, 10.0.0.0/17, …, 10.0.0.0/32, but not 10.0.0.0/8 or 10.0.0.0/9.
  • le (less-than-or-equal) — the route’s prefix must be within the rule’s prefix, and the route’s prefix length must be less-than-or-equal to the le value. 10.0.0.0/8 le 24 matches 10.0.0.0/8, 10.0.0.0/9, …, 10.0.0.0/24.
  • ge + le (range) — the route’s prefix must be within the rule’s prefix, and the route’s prefix length must be in the closed range [ge, le]. 10.0.0.0/8 ge 16 le 24 matches 10.0.0.0/16 through 10.0.0.0/24 but not 10.0.0.0/8, 10.0.0.0/9, or 10.0.0.0/25.
flowchart TB
  R["Route arrives\nwith prefix P and length L"]
  L1{"Prefix P within\nrule's prefix?"}
  L2{"Operator?"}
  E["L == rule prefix length\n(exact-match)"]
  GE["L >= ge value"]
  LE["L <= le value"]
  GR["ge <= L <= le\n(range)"]
  P["Permit"]
  X["Deny"]

  R --> L1
  L1 -->|no| X
  L1 -->|yes| L2
  L2 -->|"exact (no op)"| E
  L2 -->|"ge"| GE
  L2 -->|"le"| LE
  L2 -->|"ge+le"| GR
  E -->|"yes"| P
  E -->|"no"| X
  GE -->|"yes"| P
  GE -->|"no"| X
  LE -->|"yes"| P
  LE -->|"no"| X
  GR -->|"yes"| P
  GR -->|"no"| X

The matching engine walks the diagram from top to bottom for each rule in the list. The first rule that matches the route decides the disposition.

The configuration

The VyOS 1.5 LTS configuration tree is set policy prefix-list <name> rule <seq> ...:

# Exact-match: 192.168.1.0/24 only
set policy prefix-list ALLOW-INTERNAL rule 10 action permit
set policy prefix-list ALLOW-INTERNAL rule 10 prefix 192.168.1.0/24

# ge: anything in 10.0.0.0/8 with length 16 or greater
set policy prefix-list ALLOW-INTERNAL rule 20 action permit
set policy prefix-list ALLOW-INTERNAL rule 20 prefix 10.0.0.0/8 ge 16

# le: anything in 172.16.0.0/12 with length 24 or less
set policy prefix-list ALLOW-INTERNAL rule 30 action permit
set policy prefix-list ALLOW-INTERNAL rule 30 prefix 172.16.0.0/12 le 24

# ge+le: anything in 192.168.0.0/16 with length 17-24
set policy prefix-list ALLOW-INTERNAL rule 40 action permit
set policy prefix-list ALLOW-INTERNAL rule 40 prefix 192.168.0.0/16 ge 17 le 24

# Catch-all deny
set policy prefix-list ALLOW-INTERNAL rule 1000 action deny

The list is read top-to-bottom. The first matching rule decides. Rule 1000 is the catch-all deny (defence in depth).

Sequence numbering

VyOS 1.5 LTS sequence numbers are positive integers with a common convention of stepping by 10 (10, 20, 30, …) to leave room for insertions without renumbering:

set policy prefix-list INBOUND rule 10 action permit
set policy prefix-list INBOUND rule 10 prefix 192.168.0.0/16

set policy prefix-list INBOUND rule 20 action permit
set policy prefix-list INBOUND rule 20 prefix 10.0.0.0/8 le 24

set policy prefix-list INBOUND rule 100 action deny

To insert a new rule between 10 and 20, the operator writes rule 15. The list reorders by sequence; the matching engine walks 10 → 15 → 20 → 100.

The VyOS CLI does not auto-renumber. The operator can rewrite the rules in any sequence and the matching engine reorders on commit. The configuration file (/config/config.boot) shows the rules in the order they were last written; the matching engine walks them by sequence number, not by file order.

Exact-match vs prefix-list-of-one

A common idiom is to write set policy prefix-list FOO rule N action permit followed by set policy prefix-list FOO rule N prefix 10.0.0.0/8 (no operator). This matches only 10.0.0.0/8. It is equivalent to 10.0.0.0/8 ge 8 le 8 but cleaner.

The defensive idiom for a single-prefix filter is to write the exact-match form (no ge or le) and to comment the intent:

set policy prefix-list FROM-PEER-A rule 10 action permit
set policy prefix-list FROM-PEER-A rule 10 prefix 203.0.113.0/24

A future operator reading this configuration can tell at a glance that the rule is exact-match. If the future operator sees 203.0.113.0/24 ge 24 they know there is a ge in play; the meaning is different.

Operational commands

The operator verifies a prefix-list with:

# The configured list
show policy prefix-list INBOUND

# The matching engine's view (FRR)
vtysh -c 'show ip prefix-list'
vtysh -c 'show ip prefix-list INBOUND'

# Test a specific prefix against the list
vtysh -c 'show ip prefix-list INBOUND 192.168.1.0/24'

# Count of matching routes
vtysh -c 'show ip prefix-list INBOUND seq 10'

# Clear the hit counts (useful after a test)
clear ip prefix-list

The show ip prefix-list <name> <prefix> command returns permit or deny for the route against the list. The operator who has just written a new rule should run this command for every prefix the rule is supposed to match, and for at least one prefix the rule is supposed to reject.

Failure modes

Over-broad ge without le

The operator writes 10.0.0.0/8 ge 16. The intent was 10.0.0.0/16. The rule matches every /16 through /32. The route-map permits every more-specific in 10.0.0.0/8. A leak.

Diagnostic:

  • show policy prefix-list <name> shows the rule.
  • vtysh -c 'show ip prefix-list <name> 10.0.0.0/16' returns permit.
  • vtysh -c 'show ip prefix-list <name> 10.5.5.0/24' also returns permit. The operator expected deny.

Fix: change the rule to 10.0.0.0/16 ge 16 le 16 (exact-match on /16) or split the rule into specific prefixes.

Under-specified list with implicit deny

The operator writes three permit rules and no catch-all deny. The implicit deny at the end of the list filters any prefix the operator did not enumerate. The operator may or may not have intended the deny.

Diagnostic:

  • show ip route ... shows a missing prefix.
  • show policy prefix-list <name> shows the rule list.
  • vtysh -c 'show ip prefix-list <name> <prefix>' returns deny.
  • The deny is correct if the prefix was not supposed to be permitted; the deny is a leak risk if the prefix was supposed to be permitted.

Fix: add the missing rule with the correct sequence and prefix.

Rule 10 is too permissive; rule 20 is supposed to deny

The operator writes rule 10 permitting 10.0.0.0/8 le 24 (intending to match /8 through /24) and rule 20 denying 10.5.0.0/16 (intending to exclude the customer’s /16). A route for 10.5.0.0/16 is matched by rule 10 first (it is in 10.0.0.0/8 and the length 16 satisfies le 24); rule 20 is never consulted.

Diagnostic:

  • The route is in the BGP table when it should not be.
  • vtysh -c 'show ip prefix-list <name> 10.5.0.0/16' returns permit.
  • show policy prefix-list <name> shows rule 10 matching before rule 20.

Fix: reorder so the deny is at rule 10 and the permit is at rule 20, or make rule 10 more specific.

Rollback

A prefix-list change is reversible through VyOS’s standard mechanisms:

  • rollback N and commit to revert to a previous configuration revision.
  • delete policy prefix-list <name> and commit to remove the list entirely. The referencing route-map is left dangling; the commit validator catches this and rejects the commit.
  • delete policy prefix-list <name> rule <seq> and commit to remove a single rule.
  • set policy prefix-list <name> rule <seq> action permit (override the deny) to permit everything during a debugging window — the operator must remember to restore the deny after the window.

The VyOS commit validator rejects a route-map that references a missing prefix-list. The operator cannot silently break the reference.

Production discipline

Cross-course references

  • XXVIII-VyOS-BGPPrefixFilters covers the prefix-list in the BGP context (BGP neighbour inbound/outbound filters).
  • XIII-VyOS-PBR (route-maps) shows how the prefix-list is matched against a route in the route-map’s match clause.
  • XXXIV-VyOS-Redistribution shows the prefix-list in the redistribution route-map.

Quiz

Knowledge check · 4 questions

  1. Q1. The rule `set policy prefix-list FOO rule 10 action permit prefix 10.0.0.0/8 ge 16` matches which prefixes?

  2. Q2. An FRR prefix-list evaluates every rule and applies all matching permits.

  3. Q3. An operator writes a prefix-list with rule 10 permitting 192.168.0.0/16 le 24, rule 20 denying 192.168.1.0/24, and rule 1000 denying. A route for 192.168.1.0/24 arrives. Which rule fires and what is the disposition?

    The list is: rule 10 (192.168.0.0/16 le 24 permit), rule 20 (192.168.1.0/24 deny), rule 1000 (deny). The route 192.168.1.0/24 is evaluated.

  4. Q4. An operator wants to permit only 10.5.0.0/16 and deny everything else. They write `set policy prefix-list FOO rule 10 action permit prefix 10.5.0.0/16` and `set policy prefix-list FOO rule 20 action deny`. A route for 10.5.5.0/24 arrives. What happens?

    The intent is to permit only 10.5.0.0/16. The configuration permits 10.5.0.0/16 with no operator. Rule 20 is a catch-all deny. A more-specific 10.5.5.0/24 arrives.

Passing score: 75%. Answers are checked in this browser.