Filter before you prefer: writing a BGP edge policy that fails safe
How to structure a multi-homed BGP edge: inbound hygiene first, then a tiered local-preference scheme, outbound discipline and anti-spoofing. With examples.

Being multi-homed is not the same as being resilient. Two transit carriers and an exchange port give you options; the routing policy decides whether those options make you faster and safer, or simply give a bad route more ways in. This is how we think about an edge policy, in the order a route actually meets it.
The problem every multi-homed network has
The moment you take full tables from more than one carrier, your router is choosing between paths all day, every day, and it chooses by the rules you wrote. If you wrote none, it falls back to BGP's default tie breakers: shortest AS path, then a cascade of details that have nothing to do with latency, cost or your customers.
The common shortcut is to bolt preference onto sessions first ("prefer carrier A, it is cheaper") and add filtering later, if at all. That order is backwards. Preference is a decision about good routes. If garbage has not been removed before that decision is made, you are carefully ranking garbage.
Stage one: hygiene, before any decision
Every inbound session, transit or peer, passes through the same hygiene policy before anything else touches the route. The list is short and boring, which is the point:
- Bogons. Private, reserved, documentation and unallocated space has no business arriving from the internet.
- Your own prefixes. A route to your own space learned from outside is either a loop or a hijack. Drop it.
- The default route. Unless you asked a carrier for a default, you do not want one appearing because somebody upstream made a mistake.
- Too specific. Anything longer than a /24 for IPv4 (and a /48 for IPv6) is not globally routable by convention. Accepting it invites more-specific hijacks.
- Absurd AS paths. Paths with private ASNs in them, or paths far longer than any real route needs.
In generic Cisco IOS-XR route-policy terms, the skeleton looks like this:
route-policy TRANSIT-IN
if destination in BOGONS-V4 or destination in OUR-PREFIXES then
drop
endif
if destination in (0.0.0.0/0) then
drop
endif
if destination in (0.0.0.0/0 ge 25) then
drop
endif
if as-path in PRIVATE-ASNS then
drop
endif
apply SET-PREFERENCE
end-policy
Notice that the preference logic is applied at the very end, as a separate policy. Hygiene is identical on every session; preference differs per session. Keeping them apart means a change to steering can never accidentally weaken filtering.
Stage two: preference in tiers
Once only sane routes remain, decide which path wins. We use tiers of local preference rather than one number per carrier, because tiers describe intent:
- Direct peering wins. A route learned from the network itself, at an exchange or over a bilateral session, is the shortest path you can get.
- A carrier's own customers come next. If a transit carrier tags the routes it learns from its own customers with a community, those routes stay on that carrier's network end to end.
- Everything else goes over the transit that measures best for the bulk of traffic.
A second carrier is held hot as a standby: full table accepted, lower preference, ready the moment the first one withdraws.
One more rule earns its keep quietly: never use one transit carrier to reach another carrier's customers when the second carrier is connected to you directly. Matching on the neighbour AS in the path and lowering preference stops traffic doing an expensive detour through a third party.
Stage three: outbound discipline
The outbound side is simpler and more important. Announce exactly the prefixes you originate, and nothing else:
prefix-set OUR-PREFIXES-V4
192.0.2.0/24,
198.51.100.0/24
end-set
route-policy TRANSIT-OUT
if destination in OUR-PREFIXES-V4 then
pass
else
drop
endif
end-policy
An explicit outbound allow list means a mistake elsewhere in your network (a redistributed static, a customer route that should have stayed internal) cannot turn you into a transit path for somebody else's traffic. Return-path shaping, such as AS-path prepending toward a carrier you want to use less inbound, happens inside this policy, never instead of it.
Stage four: do not originate spoofed traffic
Routing policy controls what you believe; anti-spoofing controls what you send. BCP38 says a network should not forward packets whose source address could not legitimately come from behind the interface they arrived on. On internet-facing and customer-facing interfaces, that means unicast reverse path forwarding in strict mode where the topology allows, or explicit source-address filters where it does not. It is one of the few controls that protects the rest of the internet from you, and it is the difference between a compromised server in your network being your problem and it being everyone's.
Checking your own edge
If you run your own edge, or you want to ask your provider the right questions, here is a short checklist:
- Is hygiene applied identically on every inbound session, including exchange route servers and "trusted" peers?
- Can you show that a /25 or your own prefix sent to you by a neighbour is dropped? Test it in a lab, or read the policy line by line.
- Is your outbound policy an explicit allow list, or "everything except"?
- Do you know which carrier your traffic to the top ten destinations leaves through, and why? A traceroute from the edge plus
show bgp <prefix>answers that in minutes. - Is BCP38 filtering bound to every internet-facing interface, and do you have a test that proves it?
- Do you measure your network from outside? An independent platform such as RIPE Atlas shows how the internet actually reaches you, which is often not how your router thinks it does.
Why we bother
Every one of these steps is invisible on a good day. On the day a carrier leaks a table, takes a circuit down for maintenance, or a neighbour announces something it should not, they decide whether your traffic notices. We run our own autonomous systems with this structure on Cisco ASR 9000 and Juniper MX routers, measured continuously from outside, because that is the only way we know to make a multi-homed network behave predictably.
If you want a second pair of eyes on your own edge policy, or a platform that sits behind one built this way, we are happy to talk.
Published 22 October 2026.
All field notes