BGP Deep Dive Part 8: Policy in Practice, Prefix Filters, AS-Path Filters, and RFC 7454
Every post so far has built the raw material: attributes in Part 3, the algorithm that reads them in Part 4, communities as a general-purpose tag in Part 7. This post is about the tools that actually apply policy to that material, matching routes against conditions and either permitting, denying, or rewriting them. The exact syntax differs by vendor, Cisco’s route-map, Junos’s policy-statement, FortiOS’s own route-map implementation, all get their proper treatment in this series’ later vendor-implementation parts. What’s covered here is the shared conceptual shape underneath all of them, plus RFC 7454’s actual operational recommendations for using these tools responsibly.
Prefix filtering: matching on the destination itself
A prefix filter matches routes by network address and, critically, by a range of acceptable mask lengths, not just an exact prefix. That range matters because the real filtering decision an operator usually wants isn’t “accept this one exact prefix” but “accept this block, and anything more specific within it up to some limit, and nothing looser or more specific than that.” Both inbound and outbound directions matter for different reasons: inbound prefix filtering stops a peer from advertising address space that isn’t theirs to advertise, whether by mistake or by something worse, and outbound prefix filtering stops an operator’s own network from leaking routes it never intended to make public.
RFC 7454, the IETF’s BCP 194 on BGP operations and security, documents the practical convention most of the internet has converged on for how specific is too specific: IPv4 prefixes longer than /24 and IPv6 prefixes longer than /48 are generally neither announced nor accepted on the public internet, since carrying anything more granular doesn’t meaningfully improve reachability and does directly bloat the size of every full table it touches. A route more specific than that showing up unexpectedly is a real, well-documented signal worth filtering on rather than a theoretical edge case.
Bogon and martian filtering belongs in the same category: reserved address space, like RFC 1918 private ranges, and an operator’s own prefixes being heard back from a peer that has no legitimate reason to originate them, are both things a prefix filter should reject outright. Hearing your own address space announced by someone else is one of the more unambiguous signs something has gone wrong, whether that’s a misconfiguration or an actual hijack. The default route, 0.0.0.0/0, gets its own special handling for the same underlying reason: it’s only meaningful in an explicit customer/provider relationship where accepting a default is the point, and it’s filtered everywhere else.
AS-path filtering: matching on where a route has been
Where prefix filters match the destination, AS-path filters match the AS_PATH attribute itself, typically expressed as a regular expression against the path’s string representation. This does real work Part 4’s algorithm doesn’t do on its own: rejecting a path that’s implausibly long, which both protects local control-plane resources and is itself a useful signal that something’s wrong upstream; validating that a specific prefix actually originates from the AS expected to originate it, a crude but genuinely useful precursor to what RPKI does far more rigorously in Part 12; and catching route leaks, cases where an AS appears in a path in a position it has no business being in, most commonly a customer’s AS_PATH showing up somewhere that implies it’s providing transit between two of its own upstream providers, something it was never contracted to do.
The route-map pattern, underneath every vendor’s syntax
Every mainstream implementation converges on the same underlying shape for applying these filters as actual policy, whatever it calls the construct. An ordered, numbered sequence of terms is evaluated top to bottom; each term has one or more match conditions, a prefix-list, an AS-path filter, a community, a next-hop, in any combination; and each term that matches carries an action, permit or deny, often paired with set actions that rewrite an attribute on the route as it passes through, LOCAL_PREF, MED, communities, or AS_PATH prepending among them. Evaluation stops at the first term that matches, the same top-to-bottom, first-match-wins pattern Part 4’s best path algorithm follows for a different purpose, and there’s an implicit deny at the end for anything that matched nothing above it. Understanding this shared shape is what makes reading a genuinely unfamiliar vendor’s policy syntax for the first time tractable: the vocabulary changes, the structure underneath it almost never does.
Max-prefix limits: a safety valve, not a filter
A max-prefix limit is a different kind of control entirely, applied at the session level rather than per-route: a cap on how many prefixes will be accepted from a given peer in total before the session either stops accepting new prefixes or is torn down outright, depending on configuration. It’s not trying to distinguish good routes from bad ones the way prefix and AS-path filters do; it’s a blunt safety mechanism against a peer, misconfigured or compromised, suddenly sending a dramatically larger route set than was ever expected, protecting local resources from being consumed by a fault that isn’t the local network’s own.
Community scrubbing, and the session itself
RFC 7454 also recommends stripping incoming communities from customers and peers by default unless there’s a specific, deliberate reason to honor them, the same point Part 7 raised: a community an external party can set is effectively an external party being handed a lever over internal or downstream routing behavior, and that’s not something to grant by accident just because the attribute happens to be optional transitive by default.
Everything in this post has been about controlling what flows through a session once it exists. RFC 7454 covers the other half too, protecting the session itself, largely already covered elsewhere in this series: TCP-AO and MD5 from Part 2, and GTSM, the Generalized TTL Security Mechanism from RFC 5082, worth naming here since it hasn’t come up yet, sets the outgoing TTL to 255 and rejects anything arriving with a TTL below a configured threshold, making a spoofed packet from more than one hop away trivially easy to discard before it’s ever treated as a legitimate part of the session.
Part 9 puts all of this to direct use: traffic engineering, inbound and outbound, using nothing more exotic than the attributes and filtering tools this series has already covered, AS_PATH prepending, MED, LOCAL_PREF, and communities, applied deliberately to steer where traffic actually flows.