Export limits, and a role for every peer where routes are passed on
What other networks were told of rested on one thing: the Only to Customer mark that routes from providers, peers and route servers get as they come in. A route without it, from a session without a role or by a mistake anywhere along the way, went to every peer, from every router of ours, and nothing of ours stood in the way. export_limits are a second check, independent of the roles, the marks and the export policy. For peers above or beside us (PROVIDER, PEER, ROUTE_SERVER, and any in another AS without a role): - prefixes: only routes for these go out, learned or our own. With our and our customers' space listed, a leak of anyone else's routes goes nowhere above us. - max_prefixes: if more routes were to go out than this, none of them does. The session ends with a Cease / Administrative Shutdown whose Shutdown Communication says why (RFC 9003), and the peer is held down for its import.hold_down_seconds, so that it is told nothing rather than too much. The whole table is counted before any of it is sent. They are set at the top and hold for every such peer that has none of its own; unlike `export`, a peer's own export policy does not drop them. A peer's own export_limits take their place, and an empty one lifts them. Customers, route server clients and our own routers are not limited. A configuration in which learned routes are passed on and a peer in another AS has no role is now refused, as is accept_unconfigured_peers with learned routes: without a role, a peer's routes go to everyone and it is told of everything. This used to be a warning. At startup, a warning for each peer the limits apply to that has none, and for each originated route the limits leave out. A metric, bgp_export_limit_exceeded_total, counts the sessions ended for it. The interop lab has a phase in which a customer leaks: a route outside its space never reaches BIRD, and when more were to go than the limit, BIRD's session ends and its log has our reason. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
17045a3634
commit
9cfd3f67f0
27 files changed
+1074
-19
No files matched your search
+52
-1
@@ -29,7 +29,7 @@ cd "$(dirname "$0")/../.."
|
||||
bgp="${CARGO_TARGET_DIR:-target}/release/bgp"
|
||||
work=/tmp/ferrix-lab
|
||||
pathspace=ferrixlab
|
||||
all_phases="basics roles rpki refresh flaps restart graceful scale limits hijacks nexthops transit v6only linklocal"
|
||||
all_phases="basics roles rpki refresh flaps restart graceful scale limits hijacks nexthops transit leaks v6only linklocal"
|
||||
phases="${PHASES:-$all_phases}"
|
||||
scale_routes="${SCALE_ROUTES:-200000}"
|
||||
|
||||
@@ -959,6 +959,57 @@ control_communities: true'
|
||||
ok "back to normal"
|
||||
}
|
||||
|
||||
# A customer leaks, and the export limits hold. FRR, now our customer,
|
||||
# announces a route outside its address space and then more routes than
|
||||
# BIRD, our provider, is to be told of. A customer's routes go to
|
||||
# everyone as far as the roles go; the export limits are the check on
|
||||
# that. The route outside our and the customer's space never goes up to
|
||||
# BIRD; when more were to go than the limit allows, none of them does,
|
||||
# and the session with BIRD ends with an Administrative Shutdown that
|
||||
# says why (RFC 9003).
|
||||
phase_leaks() {
|
||||
dut_down TERM
|
||||
dut_config CUSTOMER 2000000 "" "" "" 'export { learned_routes: true }
|
||||
export_limits {
|
||||
prefixes { prefix: "10.1.0.0/16" max_length: 24 }
|
||||
prefixes { prefix: "10.2.0.0/16" max_length: 24 }
|
||||
prefixes { prefix: "2001:db8:1::/48" }
|
||||
prefixes { prefix: "2001:db8:2::/48" }
|
||||
max_prefixes: 5
|
||||
}'
|
||||
dut_up
|
||||
frr_configure "router bgp 64602" "neighbor 10.9.0.1 local-role customer" \
|
||||
"address-family ipv4 unicast" "network 10.77.0.0/24"
|
||||
wait_for "four sessions" established 4
|
||||
wait_for "the route outside the customer's space at the daemon" dut_has 10.77.0.0/24 frr4
|
||||
|
||||
# The customer's route goes up to the provider; the one outside the
|
||||
# export limits does not.
|
||||
wait_for "FRR's route at BIRD" bird_has 10.2.0.0/24
|
||||
sleep 1
|
||||
bird_has 10.77.0.0/24 && fail "BIRD was told a route outside the export limits"
|
||||
ok "a customer's route outside the export limits is not passed on to the provider"
|
||||
|
||||
# More routes than the limit: ours and the customer's two, and four
|
||||
# more of the customer's, would be six of five.
|
||||
frr_configure "router bgp 64602" "address-family ipv4 unicast" \
|
||||
"network 10.2.11.0/24" "network 10.2.12.0/24" "network 10.2.13.0/24" "network 10.2.14.0/24"
|
||||
wait_for "the export limit to end BIRD's session" \
|
||||
peer_is bird4 '.state != "Established" and (.last_error // "" | test("export limit"; "i"))'
|
||||
wait_for "BIRD to be told why" sudo grep -q "export limit of 5 routes reached" "$work/bird.log"
|
||||
bird_has 10.2.11.0/24 && fail "BIRD was told a route past the export limit"
|
||||
ok "past its export limit the provider is told nothing more, and why (Cease / Administrative Shutdown): $(peer_is bird4 '.last_error')"
|
||||
|
||||
frr_configure "router bgp 64602" "neighbor 10.9.0.1 local-role peer" "address-family ipv4 unicast" \
|
||||
"no network 10.77.0.0/24" "no network 10.2.11.0/24" "no network 10.2.12.0/24" \
|
||||
"no network 10.2.13.0/24" "no network 10.2.14.0/24"
|
||||
dut_down TERM
|
||||
dut_config
|
||||
dut_up
|
||||
converged
|
||||
ok "back to normal"
|
||||
}
|
||||
|
||||
# The exchange LAN loses its IPv4 addresses. One session over IPv6 with
|
||||
# each router carries both families, and IPv4 routes have IPv6 next hops
|
||||
# (RFC 8950), in BGP and in the kernel. Run after the rest: the lab stays
|
||||
|
||||
Reference in new issue
Block a user