Objective
By the end of this lab you will have produced a genuine route leak in your own topology, found it from a peer’s point of view, stopped it with a filter you can explain rule by rule, and then done the harder half of the job: refusing what an upstream sends you. You will finish by replacing a filter that can only say yes or no with one that also records why the answer was yes — the tag Lab 12 uses to make routing decisions.
The order matters. Most filtering material starts with the filter. This lab starts with the damage, because a prefix-list you wrote to stop something you watched happen is a prefix-list you will still understand in six months.
Architecture
Lab 10’s two routers plus a second upstream, and — this is the part that makes the leak possible — a link between the two upstreams. Without it, AS 65001 has nothing to leak to.
AS 65001 site1
router-id 192.0.2.101
dum0 198.51.100.1/24
/ \
eth1 192.0.2.1/30 eth2 192.0.2.5/30
(vmbr90) (vmbr91)
/ \
eth1 192.0.2.2/30 eth1 192.0.2.6/30
AS 65010 isp-a AS 65020 isp-b
router-id 192.0.2.102 router-id 192.0.2.103
dum0 203.0.113.1/25 dum0 203.0.113.129/25
\ /
eth2 192.0.2.9/30 ------------------- eth2 192.0.2.10/30
(vmbr92)
Three ASes, three eBGP sessions, one triangle. site1 is a small
end-site with two transit providers. isp-a and isp-b peer with each
other. Each AS originates exactly one prefix, and the two upstreams
split 203.0.113.0/24 between them so that every prefix in the topology
has one legitimate origin and two possible paths.
That triangle is the smallest topology in which the most common eBGP misconfiguration in the world is reproducible. An end-site is not supposed to carry traffic between its two upstreams. Nothing in the default configuration prevents it from offering to.
Requirements
- The completed Lab 10 topology, or 15 minutes to rebuild it. This lab adds one router and two bridges to it.
- 6 GB RAM and 24 GB disk in total across three VMs.
- VyOS 1.5 LTS on all three routers, with FRR 10.x underneath. The
direction keywords used here —
prefix-list importandprefix-list export— are the 1.4/1.5 spelling. Older VyOS and FRR’s own CLI useinandout, so material you find elsewhere will not paste cleanly. - Console access to all three VMs. Task 5 shuts a session down on
purpose. Management stays on
eth0and is never touched. - Roughly 100 minutes, of which about 25 is the topology extension.
Scenario
site1 has been running on one transit provider since Lab 10. The site
has just turned up a second, isp-b, for resilience. The two providers
also peer with each other directly, which is normal and none of the
site’s business.
Nobody has written a single line of routing policy. The sessions came up, the prefixes arrived, traffic flows, and the change is about to be closed as successful. Your job is to find out what the site is advertising before somebody else does.
Tasks
Task 1: Extend the topology and turn everything up unfiltered
Add two more isolated bridges on the hypervisor host. As in Lab 10,
these are stanzas for /etc/network/interfaces, not commands:
auto vmbr91
iface vmbr91 inet manual
bridge-ports none
bridge-stp off
bridge-fd 0
auto vmbr92
iface vmbr92 inet manual
bridge-ports none
bridge-stp off
bridge-fd 0
Apply with ifreload -a, then attach the new NICs and build the third
router:
# Run on the Proxmox host.
# Substitute the ISO volume ID exactly as `pvesm list local` prints it.
ISO=local:iso/vyos-1.5-lts-amd64.iso
STORE=local-lvm
# site1 gains a link to isp-b; isp-a gains a link to isp-b.
qm set 210 --net2 "virtio,bridge=vmbr91,firewall=0"
qm set 211 --net2 "virtio,bridge=vmbr92,firewall=0"
qm create 212 \
--name isp-b \
--memory 2048 --cores 2 --sockets 1 \
--net0 "virtio,bridge=vmbr0,firewall=0" \
--net1 "virtio,bridge=vmbr91,firewall=0" \
--net2 "virtio,bridge=vmbr92,firewall=0" \
--scsihw virtio-scsi-single \
--scsi0 "$STORE:8" \
--ide2 "$ISO,media=cdrom" \
--boot order=ide2 \
--ostype l26
qm start 212
Install VyOS on isp-b from the console with install image, then
switch its boot order to the disk and detach the ISO. Reboot site1 and
isp-a so they enumerate their new interface.
Now the configuration. On site1, add the second upstream:
configure
set interfaces ethernet eth2 address 192.0.2.5/30
set interfaces ethernet eth2 description "transit to isp-b"
set protocols bgp neighbor 192.0.2.6 remote-as 65020
set protocols bgp neighbor 192.0.2.6 description "isp-b transit, lab session"
commit
save /config/pre-lab-11.boot
save
On isp-a, change its origin to the half of 203.0.113.0/24 it owns
and add the peering session to isp-b. The delete line is a no-op if
you built isp-a fresh from the block above, and VyOS will say so
rather than failing the commit:
configure
delete interfaces dummy dum0 address 203.0.113.1/24
set interfaces dummy dum0 address 203.0.113.1/25
set interfaces dummy dum0 description "AS 65010 address space"
set interfaces ethernet eth2 address 192.0.2.9/30
set interfaces ethernet eth2 description "peering to isp-b"
set protocols bgp address-family ipv4-unicast network 203.0.113.0/25
set protocols bgp neighbor 192.0.2.10 remote-as 65020
set protocols bgp neighbor 192.0.2.10 description "isp-b peering"
commit
save /config/pre-lab-11.boot
save
On isp-b, the full baseline:
configure
set system host-name isp-b
set interfaces ethernet eth0 address dhcp
set interfaces ethernet eth0 description "management - not part of the lab"
set interfaces ethernet eth1 address 192.0.2.6/30
set interfaces ethernet eth1 description "transit to site1"
set interfaces ethernet eth2 address 192.0.2.10/30
set interfaces ethernet eth2 description "peering to isp-a"
set interfaces dummy dum0 address 203.0.113.129/25
set interfaces dummy dum0 description "AS 65020 address space"
set service ssh
set protocols bgp system-as 65020
set protocols bgp parameters router-id 192.0.2.103
set protocols bgp parameters log-neighbor-changes
set protocols bgp address-family ipv4-unicast network 203.0.113.128/25
set protocols bgp neighbor 192.0.2.5 remote-as 65001
set protocols bgp neighbor 192.0.2.5 description "site1 customer"
set protocols bgp neighbor 192.0.2.9 remote-as 65010
set protocols bgp neighbor 192.0.2.9 description "isp-a peering"
commit
save /config/pre-lab-11.boot
save
Confirm all three sessions on each router with show bgp summary before
continuing. Every neighbour should show a numeric prefix count.
Task 2: Find out what you are announcing
Do not look at site1’s configuration. Look at what isp-b received,
because that is what the rest of the world sees.
$ show bgp ipv4 unicast 203.0.113.0/25BGP routing table entry for 203.0.113.0/25
Paths: (2 available, best #1, table default)
65010
192.0.2.9 from 192.0.2.9 (192.0.2.102)
Origin IGP, valid, external, best (Shorter AS-Path)
65001 65010
192.0.2.5 from 192.0.2.5 (192.0.2.101)
Origin IGP, valid, externalIllustrative output
Read the second path. isp-b has been told that it can reach isp-a’s
address space through AS 65001 — through a small end-site with two
transit links and no business carrying anyone’s traffic but its own.
That is a route leak, and site1 created it by doing nothing at all.
Confirm it from the other direction so you know it is not an artefact of one router’s view:
$ show ip bgp neighbors 192.0.2.6 advertised-routesBGP table version is 4, local router ID is 192.0.2.101
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 198.51.100.0/24 0.0.0.0 0 32768 i
*> 203.0.113.0/25 192.0.2.1 0 0 65010 i
Total number of prefixes 2Illustrative output
Two prefixes, and the site only owns one of them. Write both captures into the journal. This pair — “what the peer holds” and “what I am sending” — is the evidence a provider will ask you for when they call about a leak, and it is worth being able to produce in under a minute.
Task 3: Stop the leak with an export filter
The rule you want is the narrowest one that is true: this AS originates
198.51.100.0/24 and announces nothing else, ever, to anybody.
configure
set policy prefix-list ONLY-MINE rule 10 action permit
set policy prefix-list ONLY-MINE rule 10 prefix 198.51.100.0/24
set policy prefix-list ONLY-MINE rule 10 description "AS 65001 allocation - the only prefix this AS originates"
set protocols bgp neighbor 192.0.2.2 address-family ipv4-unicast prefix-list export ONLY-MINE
set protocols bgp neighbor 192.0.2.6 address-family ipv4-unicast prefix-list export ONLY-MINE
commit-confirm 5
Confirm the commit, then re-run the Task 2 captures. isp-b should now
hold exactly one path for 203.0.113.0/25, and site1 should be
advertising exactly one prefix to each upstream.
$ show ip bgp neighbors 192.0.2.6 advertised-routesBGP table version is 6, local router ID is 192.0.2.101
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 198.51.100.0/24 0.0.0.0 0 32768 i
Total number of prefixes 1Illustrative output
The filter has one rule. The rule that did the work is not in it.
A prefix-list ends with an implicit deny: a route matching no rule is
rejected. 203.0.113.0/25 matched nothing, so it was dropped, and the
line responsible appears nowhere in show configuration. This is the
single most important property of a prefix-list and the one that
surprises operators in both directions — people who expect the list to
be additive are surprised when everything else vanishes, and people who
forget the implicit deny exists are surprised when adding one narrow
permit rule to an existing list silently blocks the rest.
Task 4: Refuse what the upstream sends you
Export policy protects everyone else from you. Import policy protects you from everyone else, and it is the direction most sites get wrong, because its failure mode is not an angry phone call.
Simulate a misconfigured upstream. On isp-a, originate a more-specific
of site1’s own allocation — the shape of both an accidental
mis-assignment and a deliberate hijack:
configure
set interfaces dummy dum1 address 198.51.100.129/25
set interfaces dummy dum1 description "LAB ONLY - simulated mis-origination of a customer prefix"
set protocols bgp address-family ipv4-unicast network 198.51.100.128/25
commit
Now look at what it did to site1 — not to site1’s BGP table, but to
site1’s forwarding:
$ show ip route 198.51.100.128/25Routing entry for 198.51.100.128/25
Known via "bgp", distance 20, metric 0, best
Last update 00:00:24 ago
* 192.0.2.1, via eth1, weight 1Illustrative output
$ ip route show table 254 198.51.100.128/25198.51.100.128/25 nhid 24 via 192.0.2.1 dev eth1 proto bgp metric 20Illustrative output
site1 has a connected /24 covering that space and has just installed
a /25 on top of it. Longest-prefix match does not care which route is
connected and which is learned — the /25 is more specific, so it wins.
Traffic originated by site1 for the upper half of its own LAN now goes
out the transit link to isp-a.
Prove it from the data plane and keep the capture:
$ ip route get 198.51.100.200198.51.100.200 via 192.0.2.1 dev eth1 src 192.0.2.1 uid 1000
cacheIllustrative output
Now build the import filter. Four rules, in order, each with a stated job:
configure
set policy prefix-list UPSTREAM-SANE rule 10 action deny
set policy prefix-list UPSTREAM-SANE rule 10 prefix 198.51.100.0/24
set policy prefix-list UPSTREAM-SANE rule 10 le 32
set policy prefix-list UPSTREAM-SANE rule 10 description "never accept our own space back from anyone"
set policy prefix-list UPSTREAM-SANE rule 20 action deny
set policy prefix-list UPSTREAM-SANE rule 20 prefix 0.0.0.0/0
set policy prefix-list UPSTREAM-SANE rule 20 le 7
set policy prefix-list UPSTREAM-SANE rule 20 description "reject absurdly short prefixes"
set policy prefix-list UPSTREAM-SANE rule 30 action deny
set policy prefix-list UPSTREAM-SANE rule 30 prefix 0.0.0.0/0
set policy prefix-list UPSTREAM-SANE rule 30 ge 25
set policy prefix-list UPSTREAM-SANE rule 30 description "reject anything longer than a /24"
set policy prefix-list UPSTREAM-SANE rule 40 action permit
set policy prefix-list UPSTREAM-SANE rule 40 prefix 0.0.0.0/0
set policy prefix-list UPSTREAM-SANE rule 40 le 24
set policy prefix-list UPSTREAM-SANE rule 40 description "accept everything else up to /24"
commit
Before you attach it, walk it. Write the answer for each candidate in your journal before running anything:
| Candidate prefix | Which rule matches, and what happens |
|---|---|
198.51.100.128/25 | ? |
203.0.113.0/25 | ? |
203.0.113.128/25 | ? |
0.0.0.0/0 | ? |
The first is denied by rule 10: the leading 24 bits match
198.51.100.0, and le 32 extends the rule to lengths 24 through 32.
The second and third are denied by rule 30, because 0.0.0.0/0 ge 25
matches any prefix of length 25 or more — and that is the trap in this
list. Rule 30 does exactly what its description says, and what its
description says is wrong for this topology, because both upstreams
legitimately originate /25s.
The fourth, 0.0.0.0/0, is denied by rule 20: a length of 0 is within
le 7. That is a policy choice, not an accident. A site taking full
tables from both upstreams does not want a default route as well,
because a default silently repairs any hole your own filters create and
makes a missing prefix look like a working one. A site that does want
a default from one upstream must permit it explicitly, before rule 20.
That is not an error in the lab. It is the most common way a
correctly-written filter causes an outage: a rule that encodes a
reasonable industry default (do not accept prefixes longer than /24
from the global table) applied to a link where the default does not
hold. Correct it before attaching, and note in your journal that you
caught it on paper rather than in production:
set policy prefix-list UPSTREAM-SANE rule 30 ge 26
set policy prefix-list UPSTREAM-SANE rule 30 description "reject anything longer than a /25 - upstreams here originate /25s"
set policy prefix-list UPSTREAM-SANE rule 40 le 25
set policy prefix-list UPSTREAM-SANE rule 40 description "accept everything else up to /25"
commit
Now attach it to both upstream sessions, and take the safety net with you:
set protocols bgp neighbor 192.0.2.2 address-family ipv4-unicast prefix-list import UPSTREAM-SANE
set protocols bgp neighbor 192.0.2.6 address-family ipv4-unicast prefix-list import UPSTREAM-SANE
commit-confirm 5
Confirm, then verify that the hijacked /25 is gone from the RIB and
from the kernel:
$ show ip route 198.51.100.128/25% Network not in tableIllustrative output
And confirm that the routes you do want survived — this is the check people skip, and it is the one that catches an over-broad deny rule:
$ show bgp ipv4 unicastBGP table version is 9, local router ID is 192.0.2.101, vrf id 0
Default local pref 100, local AS 65001
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 198.51.100.0/24 0.0.0.0 0 32768 i
*> 203.0.113.0/25 192.0.2.1 0 0 65010 i
*> 203.0.113.128/25 192.0.2.5 0 0 65020 i
Displayed 3 routes and 3 total pathsIllustrative output
Task 5: Revise a filter without dropping the session, and bound the damage
Changing an inbound filter raises a question BGP has to answer: the
peer already sent its routes, and the ones your old filter rejected are
gone. FRR’s default answer is route-refresh (RFC 2918) — ask the peer to
send everything again. The capability was negotiated when the session
came up; you saw it in Lab 10 as Route refresh: advertised and received.
clear ip bgp 192.0.2.2 in
The session is not reset. No prefixes are withdrawn from anywhere else,
no hold timer restarts, and the peer does the work. Confirm the session
uptime in show bgp summary did not reset — that is the whole point.
The alternative is soft-reconfiguration inbound, which keeps a local
unfiltered copy of everything the peer sent so filters can be re-applied
without asking:
configure
set protocols bgp neighbor 192.0.2.2 address-family ipv4-unicast soft-reconfiguration inbound
commit
It costs roughly a second copy of the peer’s table in memory. In this lab that is three routes; on a session carrying a full table it is hundreds of megabytes, and the course’s guidance is to rely on route-refresh and enable soft-reconfiguration only when the peer does not support it. Enable it here anyway, for one specific reason: it is what makes the pre-filter view available.
$ show ip bgp neighbors 192.0.2.2 received-routesBGP table version is 9, local router ID is 192.0.2.101
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
198.51.100.128/25 192.0.2.1 0 0 65010 i
*> 203.0.113.0/25 192.0.2.1 0 0 65010 i
*> 203.0.113.128/25 192.0.2.1 0 0 65010 65020 i
Total number of prefixes 3Illustrative output
Compare that against show ip bgp neighbors 192.0.2.2 routes, which is
the post-filter view. The difference between the two lists is your
filter, expressed as data rather than as configuration. Without
soft-reconfiguration, received-routes has nothing to read and FRR says
so — that error message is not a broken command, it is the memory bill
arriving.
Finally, the backstop. Filters are written by people, and the failure you cannot filter for is the one where your filter is wrong:
configure
set protocols bgp neighbor 192.0.2.2 address-family ipv4-unicast maximum-prefix 1
commit
One is deliberately below what isp-a legitimately sends after your
import filter has run, so the limit fires within seconds. Watch it:
$ show bgp neighbor 192.0.2.2BGP neighbor is 192.0.2.2, remote AS 65010, local AS 65001, external link
BGP state = Idle (PfxCt)
Last reset 00:00:12, Peer over prefix limit
Maximum prefixes allowed 1Illustrative output
Idle (PfxCt) is the state to recognise: the session is administratively
down because this router decided the peer was sending too much. It
stays down until you clear it. Raise the limit to something realistic
and bring it back:
configure
set protocols bgp neighbor 192.0.2.2 address-family ipv4-unicast maximum-prefix 100
commit
clear ip bgp 192.0.2.2
VyOS exposes further sub-options on the same node — a warning-only mode that logs instead of shutting down, a threshold percentage for the early warning, and an automatic restart timer. Check the exact spelling with tab completion on your build before writing any of them into a change record. The lesson on maximum-prefix recommends starting a new session in warning-only mode, watching the real prefix count for a week, and enforcing only once you know what normal looks like.
Task 6: Replace the yes/no filter with one that says why
UPSTREAM-SANE answers one question: accept or reject. That is all a
prefix-list can do. The moment you want to treat routes differently
based on where they came from — which is Lab 12’s entire subject — you
need a mechanism that can attach information as well as make a decision.
Build a route-map that reuses the prefix-list as its match condition and adds a tag:
configure
set policy route-map FROM-ISP-A rule 10 action permit
set policy route-map FROM-ISP-A rule 10 description "accept sane prefixes from isp-a and record the source"
set policy route-map FROM-ISP-A rule 10 match ip address prefix-list UPSTREAM-SANE
set policy route-map FROM-ISP-A rule 10 set community 65001:1010 additive
set policy route-map FROM-ISP-B rule 10 action permit
set policy route-map FROM-ISP-B rule 10 description "accept sane prefixes from isp-b and record the source"
set policy route-map FROM-ISP-B rule 10 match ip address prefix-list UPSTREAM-SANE
set policy route-map FROM-ISP-B rule 10 set community 65001:1020 additive
delete protocols bgp neighbor 192.0.2.2 address-family ipv4-unicast prefix-list import
delete protocols bgp neighbor 192.0.2.6 address-family ipv4-unicast prefix-list import
set protocols bgp neighbor 192.0.2.2 address-family ipv4-unicast route-map import FROM-ISP-A
set protocols bgp neighbor 192.0.2.6 address-family ipv4-unicast route-map import FROM-ISP-B
commit-confirm 5
Confirm, then read the tag back:
$ show bgp community 65001:1010BGP table version is 12, local router ID is 192.0.2.101, vrf id 0
Default local pref 100, local AS 65001
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 203.0.113.0/25 192.0.2.1 0 0 65010 i
Displayed 1 routes and 1 total pathsIllustrative output
Three details are worth writing down.
The route-map’s match ip address prefix-list UPSTREAM-SANE reuses the
filter rather than duplicating it, so there is exactly one place to
change the accepted set. Duplicating the prefix logic into the route-map
is the mistake that produces two filters which agree today and diverge
in eight months.
additive appends. Without it, set community replaces every
community already on the path, silently discarding whatever an upstream
attached — including well-known values other routers act on. Use
additive unless you have decided to erase, and record that decision.
A route-map is also an allow-list. A path matching no permit rule is
denied, exactly as with a prefix-list, so FROM-ISP-A filters and tags
in one pass. Attaching both a prefix-list and a route-map to the same
neighbour and direction makes the outcome harder to reason about; pick
one mechanism per direction and let the route-map do both jobs. That is
why the commands above delete the prefix-list attachment rather than
leaving it in place.
Validation
show ip bgp neighbors 192.0.2.6 advertised-routesonsite1returns exactly one prefix,198.51.100.0/24.show bgp ipv4 unicast 203.0.113.0/25onisp-bshows one path, via AS 65010, with no path traversing 65001.show ip route 198.51.100.128/25onsite1returns% Network not in table, and your journal contains the earlier capture proving it was in the kernel FIB before the filter existed.show bgp ipv4 unicastonsite1shows exactly three prefixes: its own/24and one/25from each upstream.- Your rule-by-rule walk of
UPSTREAM-SANEis written down, including the reason rule 30 had to change fromge 25toge 26. show bgp community 65001:1010andshow bgp community 65001:1020each return the prefixes learned from the corresponding upstream, and neither returns the other’s.show bgp summaryonsite1shows both sessions with an uptime longer than the time since your last filter change — proving the filter revisions used route-refresh rather than a session reset.- Your community registry exists and has two rows.
Expected Outcome
site1 announces its own allocation and nothing else, to either
upstream. It accepts from each upstream only prefixes that are neither
its own space, nor absurdly short, nor longer than a /25, and it tags
each accepted path with the session that admitted it. A prefix limit is
in place on the isp-a session as a backstop for a filter mistake.
isp-a still carries the simulated mis-origination of
198.51.100.128/25. Leave it: Lab 12 uses it, and a filter that is only
tested against traffic that was never going to be blocked has not been
tested.
Troubleshooting
commit fails referencing a policy that does not exist. VyOS
validates references at commit time. Define the prefix-list or route-map
in the same commit as the neighbour statement that references it, or in
an earlier one — the commands above are ordered that way deliberately.
All routes from an upstream disappear after attaching an import
filter. A deny rule matched earlier than you expected, or the permit
rule at the end does not cover what you thought. Read the pre-filter
list with received-routes (soft-reconfiguration must be on) and
compare it against routes. vtysh -c 'show ip prefix-list UPSTREAM-SANE'
prints the compiled list with its sequence numbers.
The export filter had no effect. Check the direction keyword. On
VyOS 1.4 and 1.5 the words are import and export; in and out
belong to FRR’s own CLI and to VyOS 1.3. Also check you attached it to
the neighbour you meant — an export filter on the wrong session is
invisible until somebody looks at the peer view.
A filter change appears to do nothing. The peer’s routes were sent
before the change and the new filter has not been applied to them. Run
clear ip bgp <peer> in, substituting the peer address, to trigger a
route-refresh.
The session is stuck in Idle (PfxCt). The prefix limit fired. It
does not recover on its own unless a restart timer is configured. Raise
or remove the limit, then clear ip bgp the peer.
received-routes returns an error rather than a list.
Soft-reconfiguration inbound is not enabled on that neighbour. That is
the default and usually the right default; enable it deliberately, for
as long as you need it.
Cleanup
Nothing here needs restoring for safety — the whole topology is on isolated bridges and management was never touched. The goal is a reproducible starting state.
Step 1. If you are continuing to Lab 12, stop here. Lab 12 begins
from exactly this state: three routers, filters in place, communities
being set on import, and isp-a still mis-originating
198.51.100.128/25.
Step 2. Otherwise, restore each router to the baseline saved in Task 1:
configure
load /config/pre-lab-11.boot
compare
commit
save
compare before commit shows precisely what the load will change.
Note that this returns each router to the unfiltered state — which
means the leak comes back. That is the correct baseline for re-running
the lab, and a good reminder of what “no policy” actually means.
On isp-a, also remove the simulated mis-origination:
configure
delete interfaces dummy dum1
delete protocols bgp address-family ipv4-unicast network 198.51.100.128/25
commit
save
Step 3. To remove the topology entirely, destroy the three VMs and then the three bridges.
# Run on the Proxmox host, after confirming these IDs with `qm list`.
for VMID in 210 211 212; do
qm stop "$VMID"
qm destroy "$VMID" --purge
done
Then remove the vmbr90, vmbr91 and vmbr92 stanzas from
/etc/network/interfaces and run ifreload -a.
What You Learned
- An unfiltered AS offers transit between its upstreams. You watched
isp-blearnisp-a’s space through a stub site, and nothing had gone wrong — BGP has no concept of a customer, a peer or an upstream. Those are policy, and policy is the export filter. - The rule that does the work in a prefix-list is the one you cannot type. One permit rule stopped the leak because everything else hit the implicit deny. That is why every list needs its intent recorded in a description.
- An accepted more-specific of your own space breaks your own
forwarding. The
/25beat your connected/24on longest-prefix match and went into the kernel FIB. No log entry, no alarm, and the first symptom is that half your LAN is unreachable from your own router. - The right time to find the wrong rule is on paper. Writing the
rule-by-rule walk before attaching
UPSTREAM-SANEis what caughtge 25rejecting both upstreams’ legitimate/25s. - Route-refresh changes a filter without touching the session. You revised inbound policy repeatedly with no session reset and no withdrawal storm, and you now know what soft-reconfiguration buys and what it costs.
- A route-map filters and records; a prefix-list only filters. The communities you set here are not decoration. They are the input to every routing decision in Lab 12.