VyOSXXVIII · BGP Prefix FilteringPrefix filters
Maximum-prefix — bounding the number of prefixes a BGP peer can send
What you'll learn
- Explain the maximum-prefix knob and its operational purpose
- Configure maximum-prefix under the neighbour address family with a sensible limit
- State which FRR maximum-prefix options VyOS does not expose, and what to do instead
- Read the 75% threshold log and the Idle (PfxCt) state, and recover the session
- Recognise the production failure modes around the limit being too low or too high
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-19
The maximum-prefix knob is the BGP neighbour’s safety net. It caps the number of prefixes a BGP peer can send before the local router defends itself by tearing the session down. It is the operator’s protection against a peer that accidentally — or maliciously — sends far more prefixes than the design accounts for.
The canonical use case: an operator has two upstreams. The global IPv4 table is over a million prefixes and still growing, so a full-table session is expected to carry roughly that. The operator sets a limit somewhat above today’s count — say 1,300,000 — on each upstream session. If an upstream ever sends more than that, whether from a misconfiguration, a route leak, or a hijack, the local router drops the session rather than let its RIB and its memory be filled by someone else’s mistake.
The maximum-prefix knob
maximum-prefix is a leaf under the neighbour’s address family, because a prefix limit is per address family — an IPv4 limit says nothing about how many IPv6 prefixes the same peer may send:
configure
set protocols bgp system-as 64512
set protocols bgp neighbor 192.0.2.2 remote-as '65001'
set protocols bgp neighbor 192.0.2.2 address-family ipv4-unicast maximum-prefix '1300000'
set protocols bgp neighbor 192.0.2.2 address-family ipv6-unicast maximum-prefix '250000'
commit
save
The local router counts what the peer sends. When the count exceeds the limit, the router sends a CEASE notification and drops the session.
The limit is per neighbour and per address family. It is not per AS and not per router: two sessions to the same upstream AS carry two independent limits.
There is a second, less-used leaf for the opposite direction:
set protocols bgp neighbor 192.0.2.2 address-family ipv4-unicast maximum-prefix-out '2000'
maximum-prefix-out bounds what this router will advertise to that peer. It is the knob that stops you being the one who leaks: if an internal mistake suddenly makes 900,000 prefixes eligible for export to a customer who should receive 2,000, the export is capped rather than delivered. Upstreams commonly ask for it in peering agreements, and it is the half of the pair that operators forget.
What FRR does at the threshold and at the limit
Two distinct events, and operators conflate them.
At 75% of the limit, FRR emits a log message naming the peer, the current count and the configured maximum. Nothing else happens: the session stays up and prefixes keep being accepted. 75% is FRR’s compiled-in default and, since VyOS does not expose the threshold node, it is the only value you get.
At the limit, FRR sends a CEASE notification with the “Maximum Number of Prefixes Reached” subcode and drops the session. The peer goes to Idle and stays there. There is no automatic retry: without the restart option — which VyOS does not expose — the session is down until somebody resets it.
flowchart TD
S1["Session Established"] --> S2{"prefixes >= 75% of limit?"}
S2 -->|No| S1
S2 -->|Yes| S3["Log MAXPFX<br/>session stays up"]
S3 --> S4{"prefixes > limit?"}
S4 -->|No| S1
S4 -->|Yes| S5["CEASE notification<br/>subcode: max prefixes reached"]
S5 --> S6["Idle (PfxCt)<br/>no automatic retry"]
S6 --> S7["Operator: reset bgp 192.0.2.2"]
S7 --> S1
The 75% message is the whole early-warning system, so it has to reach a human. Find it in the log by the string MAXPFX; the teardown carries a distinct string of its own, so the two events are separable in a grep:
journalctl -u frr --since '-24 hours' | grep -i maxpfx
An alert on that string, routed somewhere a person reads, is what converts maximum-prefix from “a thing that eventually breaks the session” into “a thing that warns you first”. Without the alert the 75% message lands in a file nobody opens and the first signal is the outage.
Sizing the limit, and the soft-launch that replaces warning-only
The reason operators want warning-only is that they do not yet know the peer’s real prefix count and are afraid of setting the limit too low. VyOS does not give you that mode, but it gives you the same outcome by a different route: start with a limit you are certain is too generous, watch the actual count, then tighten.
The sequence:
- Set the limit well above any plausible count for that peer — for a full-table upstream, twice the current global table. The knob is now armed against a runaway without being anywhere near a legitimate count.
- Record the real count over at least a week.
show ip bgp summaryprints it per peer in theState/PfxRcdcolumn; sampling it into whatever time-series you already run is worth more than a spot check, because the number drifts upward continuously. - Set the limit to the observed peak plus headroom. For a full table, 25-35% is the usual choice — enough to absorb a year or two of growth, tight enough that a leak of a full table into a customer session still trips it.
- Put the review on a schedule. A limit that is never revisited becomes either useless (the table grew past it and someone raised it to silence the alerts) or a landmine (the table grew into it and the session drops during a quiet week).
The counts to size against, for a customer or peering session, come from the agreement: a customer whose cone is 2,000 prefixes gets a limit in the low thousands, not the low millions. That is where maximum-prefix does its most useful work — a full-table limit on a full-table session catches almost nothing, while a tight limit on a customer session catches the classic leak on the day it happens.
Reading the down session: Idle (PfxCt)
In show ip bgp summary, the State/PfxRcd column carries the prefix count while the session is up and the reason while it is down. A session dropped by the prefix limit reads Idle (PfxCt) — that string is the diagnosis, and it is what distinguishes this from every other way a session can be idle:
State/PfxRcd | What it means |
|---|---|
| a number | Established; that many prefixes received |
Idle (PfxCt) | Dropped by maximum-prefix |
Idle (Admin) | Administratively shut down (set protocols bgp neighbor ... shutdown) |
Active / Connect | Trying to establish; the peer is not answering, or TCP is not getting through |
Reading the column rather than assuming is the point. “The session is down and I have a maximum-prefix configured” is not evidence that maximum-prefix dropped it; Idle (PfxCt) is.
Once identified, there are three real options:
- Increase the limit, if the count that tripped it is legitimate.
- Remove the limit, if it should never have been on this session.
- Leave it down and go and talk to the peer, if the count is not legitimate. This is the correct answer more often than operators like.
Resetting the session without doing one of those three simply repeats the sequence.
Recovery is manual
Because VyOS does not expose the restart timer, a session dropped by the prefix limit stays down until an operator brings it back:
reset bgp 192.0.2.2
FRR’s own spelling of the same action is reachable through vtysh:
vtysh -c 'clear bgp 192.0.2.2'
Either way the prefix count starts again from zero on the new session. If the peer is still sending too much, the count climbs back through 75%, past the limit, and the session drops again — so resetting before the peer has fixed anything buys a few minutes of table churn and nothing else.
That is an argument for the manual behaviour rather than against it. An automatic restart timer turns a stable “down and alarming” state into a flap on a fixed cadence, and a flap is harder to diagnose and noisier for every downstream than a session that is simply down. Resist the temptation to reproduce the missing timer with a cron job that resets the peer: the same instinct produces the “make sure the session is up” scripts that turn one bad afternoon into a week of route churn.
The three real decisions when the session is down are: raise the limit because it was wrong, leave it down because the peer is genuinely misbehaving, or fix the peer and then reset. Nothing else helps.
The configuration discipline
The maximum-prefix configuration discipline:
- Derive the limit from the relationship, not from a habit. A customer session is sized from the agreed prefix count; a transit session is sized from the global table. The two differ by three orders of magnitude and the same number is wrong for both.
- Start generous, then tighten. VyOS has no warning-only mode, so the soft launch is a deliberately loose limit plus a week of observation. Tighten once you know the real count.
- Alert on the 75% message. It is the only warning FRR gives you and it is not tunable. A
MAXPFXline that nobody sees is the same as no early warning at all. - Set
maximum-prefix-outon customer sessions too. It bounds what you leak outward, which is the half operators skip. - Put the review on a calendar. The global table grows; a limit set once and forgotten will either be raised in a panic or trip on a quiet Sunday.
The operator who follows the discipline avoids both the “session dropped because the limit was too low” failure and the quieter “limit so high it has never done anything” failure.
The canonical patterns
VyOS gives two settings, so there are two patterns and a sizing decision — not four modes.
Pattern 1: bound what a customer or peering session may send.
set protocols bgp neighbor 192.0.2.2 address-family ipv4-unicast maximum-prefix '5000'
Sized from the agreed prefix count with headroom. This is the pattern that catches real leaks.
Pattern 2: bound both directions on a customer session.
set protocols bgp neighbor 192.0.2.2 address-family ipv4-unicast maximum-prefix '5000'
set protocols bgp neighbor 192.0.2.2 address-family ipv4-unicast maximum-prefix-out '2000'
The inbound limit protects you from the customer; the outbound limit protects the customer — and your reputation — from you.
Sizing a full-table upstream.
set protocols bgp neighbor 198.51.100.1 address-family ipv4-unicast maximum-prefix '1300000'
set protocols bgp neighbor 2001:db8::1 address-family ipv6-unicast maximum-prefix '250000'
Above the current global table with room to grow, reviewed on a schedule. Note the separate IPv6 limit: it is a different address family with a different table size, and a single IPv4 setting does not bound it.
There is no fourth pattern with warning-only or restart in it, because those words have no VyOS node. If you find one in an older runbook, it came from FRR’s or Cisco’s grammar rather than from a VyOS router.
The show ip bgp summary evidence
The operator confirms the maximum-prefix limit is effective with:
show ip bgp summary prints one row per neighbour. The columns vary a little between FRR releases — there are counters for messages, table version, and the input and output queues that are not relevant here — but two of them always are: Up/Down, which is how long the session has held its current state, and State/PfxRcd.
Read State/PfxRcd first:
- A number means the session is Established and that is how many prefixes the peer has sent. Compare it against the configured limit; the ratio, not the absolute count, is what tells you whether the limit is about to matter.
Idle (PfxCt)means this mechanism dropped the session. Go to the log for the count that tripped it.- Anything else means the session is down for a different reason, and maximum-prefix is not the thing to investigate.
Up/Down is the second reading. A session that has been Established for weeks with a count near the limit is a session about to drop during someone else’s routine maintenance; a session whose Up/Down keeps resetting to a few minutes is already flapping, and if it reads Idle (PfxCt) between the resets, something is resetting it automatically.
How the result is validated
From VyOS operational mode:
show ip bgp summary
show ip bgp neighbors 192.0.2.2
show ip bgp neighbors 192.0.2.2 routes
show configuration commands | match maximum-prefix
The first gives the count and the state per peer. The second prints the peer’s full record, including the limit FRR is enforcing and how many prefixes have been accepted. The third lists what the peer actually sent, which is how you find out what the extra prefixes were — usually the most useful question, because “a customer suddenly sent 400,000 prefixes” and “a customer sent 40 more than agreed” are different incidents. The fourth reads the limits back out of the VyOS configuration, which is the authoritative place they live.
From the shell, for the log and the rendered FRR view:
journalctl -u frr --since '-24 hours' | grep -i maxpfx
vtysh -c 'show running-config' | grep -i maximum-prefix
The first separates the 75% threshold messages from the teardown; the second confirms VyOS rendered the limit where you meant it to go. A limit that appears in show configuration commands but not in the FRR running configuration means the commit did not take — check for a failed commit before assuming the mechanism is broken.
How it fails
The production failure modes the engineer must recognise:
- The limit is set too low. A limit of 100,000 on a full-table upstream drops the session as soon as it converges. The signature is a session that never reaches a stable Established state: it comes up, climbs, and goes to
Idle (PfxCt)every time. The fix is to raise the limit — and to ask why the number was chosen, because it usually came from a template written for a customer session. - The limit is set so high it never fires. A limit of five million on any session is decoration. It costs nothing, protects nothing, and shows up green on every audit. The fix is to size it from the peer’s real count, and the tell is that the ratio in
show ip bgp summaryhas never been above a few percent. - The limit is on the wrong address family. A generous IPv4 limit and no IPv6 limit is the common shape, because IPv6 is configured later and the limit is not copied across. The IPv6 table is smaller, so an IPv6 leak is a smaller number of prefixes — and completely unbounded.
- The 75% message goes nowhere. The mechanism warned, and the warning landed in a log file nobody reads, so the first human signal was the session dropping. This is the most common failure of all, and it is not a configuration failure on the router.
- The session is reset on a timer. Someone reproduces the missing
restartoption with a cron job or a monitoring “self-heal” action. The session now flaps at that cadence for as long as the peer misbehaves, the route churn propagates to everyone downstream, and theIdle (PfxCt)evidence is gone by the time anybody looks. The fix is to delete the job. - The session is idle for an unrelated reason.
Idle (Admin),ActiveandConnectare not this mechanism. Read theState/PfxRcdstring before reaching for the limit.
Rollback
Maximum-prefix configuration changes are configuration changes. The standard rollback path applies:
comparebeforecommitto see the maximum-prefix addition.commit-confirm 10for any remote change, which reverts after ten minutes unless a secondcommitconfirms it.rollback N; commit; saveto revert to the previous configuration.load /config/archive/<known-good-file>; commit; saveto revert to a specific snapshot.
The operator who changes a maximum-prefix limit on a production router must also know how to roll back the change. The standard rollback is rollback 1; commit; save — the previous configuration had the old maximum-prefix, so the rollback restores it.
If the session is down because of the maximum-prefix limit, the operator brings it back with:
reset bgp 192.0.2.2
The session re-establishes and the prefix count starts again from zero — which means the reset accomplishes nothing at all unless the limit was raised or the peer was fixed first.
Production discipline
Cross-course references
The Linux course’s XIX-Linux-NetFoundations covers the kernel FIB. The OPNsense course’s XXX-OPNsense-DynamicRouting covers the same FRR maximum-prefix pattern on the firewall side. The BGP lessons vyos-xxviii-03-distribute-list (the distribute-list for prefix filtering), vyos-xxviii-04-filter-list (the AS-path-list for AS filtering), and vyos-xxviii-01-prefix-list-concept (the prefix-list semantics) cover the broader context. The lesson vyos-xxviii-06-filter-troubleshoot walks the debugging of filter failures.
Quiz
Knowledge check · 4 questions
Q1. A VyOS 1.5 router has `set protocols bgp neighbor 192.0.2.2 address-family ipv4-unicast maximum-prefix 5000` and nothing else. The peer sends its 5001st prefix. What happens?
Q2. FRR supports a warning-only mode, a threshold percentage and a restart timer on `maximum-prefix`, but the VyOS 1.5 configuration tree exposes none of them — the only settings are the limit itself and `maximum-prefix-out`.
Q3. An operator copies a customer-session template onto a new transit session and ends up with `maximum-prefix 100000` on an upstream that sends a full table. The session comes up, climbs, and drops — repeatedly. Diagnose it and fix it.
The upstream carries the full IPv4 table, currently a little over 1,000,000 prefixes. The configured limit is 100,000. The session reaches Established, the prefix count climbs, and the session drops. It has done this several times in an hour.
Q4. Every BGP session on a router carries `maximum-prefix 2000000`, including the sessions to customers whose agreed cone is 2,000 prefixes. An audit records the routers as protected. A customer then leaks their other upstream's full table and the router accepts all of it. Why did the mechanism not help, and what should have been configured?
One number, 2,000,000, is applied to every neighbour: two full-table transit sessions and forty customer sessions with cones between 50 and 5,000 prefixes. A customer misconfigures their edge and re-advertises roughly a million prefixes. The session stays Established throughout and the router installs them.
Passing score: 75%. Answers are checked in this browser.