Advertising every route to every neighbor is the default, not a requirement. Sometimes a spoke should never learn the DMZ prefixes, a lab block should stay invisible to production, or a partner connection should see exactly three networks and nothing else. In EIGRP the tool for this is the distribute list, powered by a prefix list or a route map. This article configures both flavors on a live CML lab with before-and-after routing tables, and covers the operational habits that keep filtering from turning into a mystery outage. It assumes the baseline from the EIGRP complete guide.
Where EIGRP Filtering Happens
A distribute list attaches to the EIGRP process in a direction: out filters what you advertise, in filters what you accept, and either can be scoped to a single interface. Filtering out at the route owner is the cleanest pattern, because the prefix never enters the rest of the network at all. Filtering in protects one router from what a neighbor sends. A useful mental model: a distribute list is policy about knowledge, where an ACL on an interface is policy about packets. A filtered route means nobody can route there; the traffic never even gets a chance to be dropped.
One EIGRP-specific behavior worth knowing before you start: changing distribute-list policy causes the router to resync affected adjacencies (a graceful restart, visible in the logs) so the new policy propagates. It is non-disruptive to forwarding, but it explains the resync log lines you will see.
The Lab: Four Routes, Two of Them Private
R3 owns four /24s (10.1.0.0 through 10.1.3.0, configured as loopbacks). Treat 10.1.2.0/24 and 10.1.3.0/24 as lab-only networks that must not leak. The baseline on R1:
R1# show ip route eigrp | include 10.1.
D 10.1.0.0/24 [90/3584000] via 10.0.13.2, 00:00:16, Ethernet0/2
D 10.1.1.0/24 [90/3584000] via 10.0.13.2, 00:00:16, Ethernet0/2
D 10.1.2.0/24 [90/3584000] via 10.0.13.2, 00:00:16, Ethernet0/2
D 10.1.3.0/24 [90/3584000] via 10.0.13.2, 00:00:16, Ethernet0/2Option 1: Distribute List with a Prefix List
Prefix lists are the right default for route filtering: faster to evaluate than ACLs, explicit about masks, and readable six months later. Deny the two lab networks, permit everything else (a prefix list, like an ACL, ends in an implicit deny, so the catch-all permit is mandatory):
R3(config)# ip prefix-list BLOCK-LAB-NETS seq 5 deny 10.1.2.0/24
R3(config)# ip prefix-list BLOCK-LAB-NETS seq 10 deny 10.1.3.0/24
R3(config)# ip prefix-list BLOCK-LAB-NETS seq 15 permit 0.0.0.0/0 le 32
R3(config)# router eigrp 100
R3(config-router)# distribute-list prefix BLOCK-LAB-NETS outpermit 0.0.0.0/0 le 32 means "any prefix of any length", which is the standard catch-all (bare permit 0.0.0.0/0 would match only a literal default route). In named mode the same command goes under the topology base:
R2(config-router-af)# topology base
R2(config-router-af-topology)# distribute-list prefix BLOCK-LAB-NETS outThe after picture on R1, with the two lab networks gone:
R1# show ip route eigrp | include 10.1.
D 10.1.0.0/24 [90/3584000] via 10.0.13.2, 00:02:18, Ethernet0/2
D 10.1.1.0/24 [90/3584000] via 10.0.13.2, 00:02:18, Ethernet0/2And the verification command that should be in your muscle memory, because it is how you find filters you forgot about:
R3# show ip protocols | include filter
Outgoing update filter list for all interfaces is (prefix-list) BLOCK-LAB-NETS
Incoming update filter list for all interfaces is not set
R3# show ip prefix-list BLOCK-LAB-NETS
ip prefix-list BLOCK-LAB-NETS: 3 entries
seq 5 deny 10.1.2.0/24
seq 10 deny 10.1.3.0/24
seq 15 permit 0.0.0.0/0 le 32Option 2: Distribute List with a Route Map
A route map does everything the prefix list does, plus richer matching (tags, metrics, sources) and the ability to grow into set actions later. The pattern inverts the logic: the prefix list now permits the networks you want to act on, and the route map denies them:
R3(config)# ip prefix-list LAB-DMZ seq 5 permit 10.1.2.0/24
R3(config)# ip prefix-list LAB-DMZ seq 10 permit 10.1.3.0/24
R3(config)# route-map EIGRP-OUT deny 10
R3(config-route-map)# match ip address prefix-list LAB-DMZ
R3(config-route-map)# route-map EIGRP-OUT permit 20
R3(config)# router eigrp 100
R3(config-router)# distribute-list route-map EIGRP-OUT outThe empty permit 20 stanza is the route map's catch-all; without it, the implicit deny filters everything (a spectacular way to empty your neighbors' routing tables). Verify:
R3# show route-map EIGRP-OUT
route-map EIGRP-OUT, deny, sequence 10
Match clauses:
ip address prefix-lists: LAB-DMZ
Set clauses:
route-map EIGRP-OUT, permit, sequence 20
Match clauses:
Set clauses:The result on R1 is identical to the prefix-list version: 10.1.0.0/24 and 10.1.1.0/24 present, the other two filtered.
Reach for a prefix list when
The policy is purely "these prefixes yes, those no". Simplest to read, fastest to evaluate, hardest to get subtly wrong.
Reach for a route map when
You need multiple match criteria, route tags, or you expect the policy to grow. The deny/permit stanza structure scales; a bare prefix list does not.
Scoping to One Neighbor
Both forms accept an interface at the end, which turns a process-wide policy into a per-neighbor one:
R3(config-router)# distribute-list prefix BLOCK-LAB-NETS out Ethernet0/1Now only the neighbor on Ethernet0/1 gets the filtered view; the neighbor on Ethernet0/2 still sees everything. This is the mechanism behind "partner sees three routes, core sees all" designs. It also composes with summarization: filter what must not exist, summarize what remains (see the summarization and default routes guide, since a summary-address is itself a blunt form of filtering through suppression).
The Other Knobs: Offset Lists and Distance
Filtering is binary: a route exists for a neighbor or it does not. Two sibling tools cover the gray area in between, and knowing all three keeps you from misusing any of them.
Offset lists add a value to the metric of matching routes, in or out, optionally per interface. That makes a path less attractive without hiding it, which is often what people actually wanted when they reached for a filter:
R3(config)# access-list 11 permit 10.1.1.0 0.0.0.255
R3(config)# router eigrp 100
R3(config-router)# offset-list 11 out 500000 Ethernet0/1Neighbors beyond Ethernet0/1 still learn 10.1.1.0/24, just with half a million extra metric units, so they prefer any other path and keep this one as a working backup. Offset lists are also the surgical way to fix a feasibility problem for one prefix when tuning interface delay would disturb everything else (the interplay is in the variance guide).
Administrative distance can be weaponized as a filter of last resort: distance 255 <source> <acl> tells the router to disbelieve matching routes entirely (AD 255 is never installed). It is occasionally the only tool that works on received routes you cannot filter at the source, but it acts on this router alone, and the route still occupies topology table space. Prefer a real distribute list when you have the choice; the AD mechanics are covered in EIGRP administrative distance.
What Happens on the Wire When You Apply a Filter
Apply or change a distribute list and you will see this in the log:
*Jul 11 05:26:52.068: %DUAL-5-NBRCHANGE: EIGRP-IPv4 100: Neighbor 10.0.35.2
(Ethernet0/2) is resync: peer graceful-restartEIGRP has no mechanism to say "forget just these prefixes," so it performs a graceful resync: the router re-advertises its (now filtered) view to affected neighbors, who reconcile their tables. Forwarding continues throughout, adjacencies do not drop, and uptime counters in show ip eigrp neighbors keep counting. Knowing this matters in two directions: do not panic when a planned filter change logs NBRCHANGE resync lines, and conversely, unexplained resync lines in the log are evidence that someone changed routing policy, which is a lead worth following during an incident.
Operational Habits That Save You Later
- Document the intent in the name. BLOCK-LAB-NETS tells the next engineer what it does. PL-1 does not.
- Always end with an explicit catch-all. Both the implicit deny at the end of a prefix list and the implicit deny at the end of a route map have erased entire routing tables. Write the permit; do not rely on memory.
- Check for filters first when routes are missing.
show ip protocolsshows both directions in two lines. It is the fastest "is anyone filtering?" test on the platform, and it is step two of the workflow in troubleshooting EIGRP missing routes. - Filter at the source when you can. An
outfilter at the route owner keeps the prefix out of every topology table; aninfilter on twelve routers is twelve chances to miss one.
Worth knowing for context: this same distribute-list grammar is legacy in BGP, where route maps and prefix lists attach per neighbor instead (the BGP complete guide covers that model), and OSPF can only filter at area boundaries or into the RIB because of its link-state flooding rules. EIGRP's distance vector nature is what makes per-neighbor knowledge control this clean.
Key Takeaways
- Distribute lists filter EIGRP routing knowledge, in or out, process-wide or per interface. Filtered routes never reach the neighbor's topology table.
- Prefix lists are the readable default; route maps buy multi-criteria matching and room to grow. Both end in an implicit deny, so the explicit catch-all permit is not optional.
- In named mode the command lives under topology base; classic mode puts it directly under the process. Same syntax otherwise.
- Scope filters to an interface for per-neighbor policy, and prefer filtering out at the source over filtering in everywhere else.
show ip protocolsexposes active filters in both directions and belongs at the top of every missing-route investigation.
Route filtering is how you decide who knows what, which in a routed network is the same as deciding who can reach what. For the full picture of EIGRP policy, metrics, and design, head back to the EIGRP complete guide.