Skip to content
LinkState
Go back

IX route-server containment without trusting member filters

Introduction to Containment Patterns

Containment patterns limit the propagation of routing information to a defined trust boundary. For an Internet Exchange (IX) route server they prevent an undisciplined participant from injecting routes that could affect other members or the global routing table. The three complementary mechanisms are:

  1. BGP Communities – optional transitive attributes that can be matched and acted upon by downstream peers.
  2. Per‑Member Policy – individualized import/export filters applied per peer‑ASN (or per‑peer‑session) on the route server.
  3. Fail‑Closed Defaults – a policy stance where, in the absence of an explicit permit, the route server denies the advertisement.

Layered together they provide defense‑in‑depth, reducing the blast‑radius of routing mistakes while preserving the IX’s value proposition of open, low‑latency peering.

IX Route Server Overview

An IX route speaker peers with all members and optionally redistributes routes between them. It does not forward packets; its sole function is to disseminate reachability information.

PropertyTypical ImplementationRelevance to Containment
Peering ModelFull‑mesh via multihop BGP sessions (often with a route‑server ASN)Central point for policy insertion
Route ProcessingImport → optional modification → export (no forwarding)Policy can be applied before re‑advertisement
Default BehaviorVendor‑specific; many default to accept‑all unless filteredNecessitates explicit fail‑closed stance
ScaleHundreds‑to‑thousands of peers; millions of prefixesDrives scaling considerations for per‑member policy
ObservabilityBMP, flowspec, log‑export, MRT dumpProvides data for validation and drift detection

Because the route server sits in the forwarding‑plane‑adjacent control plane, any policy misconfiguration directly yields observable routing anomalies (unintended transit, blackholing). Containment patterns must therefore be evaluated for both intended behavior and observable outcomes.


Containment Pattern Evaluation

1. BGP Communities

Communities are 4‑octet values that can be attached to a route at origination or modified en route. They are advisory: a router acts on a community only if its import/export policy includes a match statement. In an IX they can signal geographic scope, service type, or trust level (e.g., 65000:999 for “do not re‑advertise to transit peers”).

Policy path

  1. Peer‑A sends route R with community C.
  2. Route server receives R (import policy permits all).
  3. Route server optionally modifies community (e.g., adds IX:NO_EXPORT).
  4. On export to Peer‑B, the export policy matches C and either permits or denies the route.
    If the export policy lacks the community match, containment fails and the route propagates.

Configuration examples

FRR

# peer‑server.conf
router bgp 65000
  neighbor IX-PEERS peer-group
  neighbor IX-PEERS remote-as 65000
  neighbor IX-PEERS route-server-client
  !
  address-family ipv4 unicast
    neighbor IX-PEERS route-map IMPORT-ALL in
    neighbor IX-PEERS route-map EXPORT-DROP-NO-EXPORT out
  exit-address-family
!
route-map IMPORT-ALL permit 10
  set local-preference 100
!
route-map EXPORT-DROP-NO-EXPORT deny 10
  match community IX_NO_EXPORT
!
route-map EXPORT-DROP-NO-EXPORT permit 20
!
ip community-list standard IX_NO_EXPORT permit 65000:999

Juniper Junos

routing-options {
    autonomous-system 65000;
}
protocols {
    bgp {
        group IX-PEERS {
            type internal;
            local-address 198.51.100.1;
            neighbor 203.0.113.0/24;
            import [ IMPORT-ALL ];
            export [ EXPORT-DROP-NO-EXPORT ];
            route-reflector-client;
        }
    }
}
policy-options {
    policy-statement IMPORT-ALL {
        then accept;
    }
    policy-statement EXPORT-DROP-NO-EXPORT {
        term no-export {
            from {
                community [ IX_NO_EXPORT ];
            }
            then reject;
        }
        term else {
            then accept;
        }
    }
    community IX_NO_EXPORT members [ 65000:999 ];
}

Cisco IOS‑XR

router bgp 65000
 bgp router-id 198.51.100.1
 address-family ipv4 unicast
 !
 neighbor-group IX-PEERS
  remote-as 65000
  address-family ipv4 unicast
   route-policy IMPORT-ALL in
   route-policy EXPORT-DROP-NO-EXPORT out
  !
 !
 !
route-policy IMPORT-ALL
  pass
end-policy
!
route-policy EXPORT-DROP-NO-EXPORT
  if community matches-any (65000:999) then
    drop
  else
    pass
  endif
end-policy
!
community-set IX_NO_EXPORT
  65000:999
end-set

Observability


2. Per‑Member Policy

Per‑member policy assigns a distinct import/export filter set to each peer‑ASN (or BGP session). It provides the strongest containment because it can block specific prefixes, AS‑paths, or communities on a per‑peer basis, independent of the peer’s own filtering discipline.

Design choices

ChoiceImpactObservability
Static prefix lists per peerGuarantees only pre‑approved prefixes are re‑advertised; requires manual updates for new address space.show ip prefix-list <name>
AS‑PATH ACLs per peerPrevents transit leakage (e.g., reject paths containing the peer’s own ASN as transit).show bgp ipv4 unicast regexp <pattern>
Dynamic policy via RPKI/ROAUses cryptographically validated origin authorizations; reduces manual prefix list maintenance.show rpki validation
Policy generation scriptsScales to hundreds of peers by rendering config from a source of truth (NetBox, PeeringDB).Drift detection via diff against generated config.

Policy path for prefix P from peer A to peer B

  1. Import at route server from A – applies IMPORT_A (may filter via prefix list, RPKI, etc.).
  2. Optional modification (e.g., add IX community, set local‑pref).
  3. Export to B – applies EXPORT_B (may reject based on B’s prefix list, AS‑PATH ACL, etc.).
    If either IMPORT_A or EXPORT_B denies P, the route is not installed in B’s RIB, achieving containment.

Scalable configuration example (FRR + Jinja2)

CSV (members.csv)

asn,ipv4_prefix,ipv6_prefix,export_limit
65001,203.0.113.0/24,2001:db8:1::/48,1000
65002,198.51.100.0/24,2001:db8:2::/48,500
...

Jinja2 template (frr_peer.j2)

router bgp 65000
  neighbor {{ ipv4 }} peer-group
  neighbor {{ ipv4 }} remote-as {{ asn }}
  neighbor {{ ipv4 }} route-server-client
  !
  address-family ipv4 unicast
    neighbor {{ ipv4 }} route-map IMPORT-{{ asn }} in
    neighbor {{ ipv4 }} route-map EXPORT-{{ asn }} out
  exit-address-family
!
route-map IMPORT-{{ asn }} permit 10
  match ip address prefix-list PREFIX-{{ asn }}
  set local-preference 120
!
route-map IMPORT-{{ asn }} deny 20
!
route-map EXPORT-{{ asn }} permit 10
  match ip address prefix-list PREFIX-{{ asn }}
  set community 65000:999 additive
!
route-map EXPORT-{{ asn }} deny 20
!
ip prefix-list PREFIX-{{ asn }} seq 5 permit {{ ipv4_prefix }} le 32

Generation command

for line in $(tail -n +2 members.csv); do
  IFS=',' read -r asn ipv4 ipv6 limit <<< "$line"
  jinja2 frr_peer.j2 -D asn=$asn -D ipv4=$ipv4 -D ipv6=$ipv6 -D export_limit=$limit >> frr_generated.conf
done

Resulting per‑member policy

Observability


3. Fail‑Closed Defaults

A fail‑closed stance means that, absent an explicit permit, the route server denies the advertisement. This is the baseline that makes both community‑based and per‑member policies effective: without it, a missing match would silently allow propagation.

Implementation tips

Verification


Conclusion

Combining BGP communities, granular per‑member policy, and fail‑closed defaults creates layered containment for IX route servers. Communities provide a lightweight, advisory signal that downstream peers can honor; per‑member policy enforces strict, peer‑specific limits; fail‑closed defaults guarantee that any gap in matching results in denial rather than silent acceptance. Proper configuration, as illustrated, together with routine observability checks, ensures that a misbehaving participant’s routing mistakes remain isolated, preserving the integrity of the IX and the broader Internet.


Share this post on:

Previous Post
Which drops were qdisc and which were memory
Next Post
Following a TAP frame into the host bridge