[Bug]: AS_PATH containing AS 0 is accepted, missing RFC 7607 validation
Hello BIRD maintainers, I would like to report a possible RFC 7607 compliance issue in BIRD's BGP UPDATE validation: routes whose AS_PATH contains AS number 0 appear to be accepted into the BGP table instead of being treated as malformed. Summary BIRD appears not to reject AS 0 when it appears inside the AS_PATH path attribute. I tested this with an eBGP session where the peer sent a valid UPDATE whose AS_PATH was: 65002 0 BIRD accepted the route and displayed the AS_PATH with the reserved AS 0 still present. RFC 7607 Section 2 states that a BGP speaker must not originate or propagate a route with AS number 0 in AS_PATH, and that an UPDATE containing AS number 0 in AS_PATH must be considered malformed and handled according to RFC 7606. For a malformed AS_PATH attribute with parseable NLRI, RFC 7606 handling should be treat-as-withdraw: the route should not be installed, while the BGP session should remain established. Affected Version I reproduced this on: BIRD version 2.19.0+branch.master.880200b1f94c commit 880200b1 Observed Behavior After establishing an eBGP session, the peer sent an UPDATE for 192.0.2.0/24 with: ORIGIN: IGP AS_PATH: 65002 0 NEXT_HOP: 10.0.0.2 NLRI: 192.0.2.0/24 BIRD accepted the UPDATE. birdc show route 192.0.2.0/24 all showed: Table master4:192.0.2.0/24 unreachable [as0_test ... from 10.100.0.2] * (100) [AS0i] Type: BGP univ BGP.origin: IGP BGP.as_path: 65002 0 BGP.next_hop: 10.0.0.2 BGP.local_pref: 100 The route was marked unreachable because of next-hop resolution in the local test setup, but the important point is that the route was accepted into the BGP table with: BGP.as_path: 65002 0 I did not observe an error, warning, or treat-as-withdraw behavior for the reserved AS 0. The BIRD log showed the UPDATE being accepted: as0_test: BGP session established as0_test: Got UPDATE as0_test.ipv4 > added [best] 192.0.2.0/24 ... Expected Behavior BIRD should detect AS 0 in AS_PATH and treat the UPDATE as malformed. Since the UPDATE contains reachable NLRI and the NLRI is parseable, the expected behavior is: - do not install the route, - keep the BGP session established, - handle the route using treat-as-withdraw, consistent with RFC 7606 error handling for malformed AS_PATH attributes. Source-Level Analysis The AS_PATH decoder validates AS_PATH structure but does not appear to validate individual AS numbers against the reserved AS 0 value. In proto/bgp/attrs.c, bgp_decode_as_path() calls as_path_valid() and then stores the attribute: if (!as_path_valid(data, len, as_length, as_sets, as_confed, err, sizeof(err))) WITHDRAW("Malformed AS_PATH attribute - %s", err); ... bgp_set_attr_data(to, s->pool, BA_AS_PATH, flags, data, len); The later post-decode checks in bgp_decode_attrs() cover mandatory attribute presence, local-AS loop detection, confederation loop detection, ORIGINATOR_ID loop detection, and CLUSTER_LIST loop detection, but I could not find a check for AS 0: if (bgp_as_path_loopy(p, attrs, p->local_as)) goto loop; if ((p->public_as != p->local_as) && bgp_as_path_loopy(p, attrs, p->public_as)) goto loop; In nest/a-path.c, as_path_valid() checks segment framing, segment type, whether AS_SET / AS_CONFED_* are allowed, and zero-length segments: switch (type) { case AS_PATH_SET: if (!sets) BAD("AS_SET segment", type); break; case AS_PATH_SEQUENCE: break; case AS_PATH_CONFED_SEQUENCE: if (!confed) BAD("AS_CONFED_SEQUENCE segment", type); break; case AS_PATH_CONFED_SET: if (!sets || !confed) BAD("AS_CONFED_SET segment", type); break; default: BAD("unknown segment", type); } if (pos[1] == 0) BAD("zero-length segment", type); I did not find an equivalent validation pass that iterates through the AS numbers in the path and rejects asn == 0. Suggested Fix Add AS 0 validation during AS_PATH parsing or immediately after AS_PATH decoding. Conceptually: /* RFC 7607: AS 0 is reserved and must not appear in AS_PATH */ if (as_path_contains_as_zero(...)) WITHDRAW("Malformed AS_PATH attribute - AS 0 is reserved"); A similar validation may also be relevant for AS4_PATH, AGGREGATOR, and AS4_AGGREGATOR, since RFC 7607 also covers those attributes. However, this report only describes the AS_PATH case that I reproduced dynamically. Impact Accepting AS 0 in AS_PATH can cause interoperability and policy issues: - routes accepted by BIRD may later be rejected by stricter BGP speakers, - AS_PATH-based filters may behave unexpectedly, - reserved-AS input is allowed into routing policy and best-path processing, - this appears inconsistent with RFC 7607's reserved-AS handling. This does not require tearing down the BGP session. Treat-as-withdraw should be sufficient and would match the usual RFC 7606 approach for malformed AS_PATH attributes. Please let me know if you would like a minimal reproducer or packet capture. Best regards, Xinzhe Liu
On Sun, Jul 05, 2026 at 08:24:55PM +0800, xinzhe liu via Bird-users wrote:
Hello BIRD maintainers,
I would like to report a possible RFC 7607 compliance issue in BIRD's BGP UPDATE validation: routes whose AS_PATH contains AS number 0 appear to be accepted into the BGP table instead of being treated as malformed. Summary
BIRD appears not to reject AS 0 when it appears inside the AS_PATH path attribute.
I tested this with an eBGP session where the peer sent a valid UPDATE whose AS_PATH was:
65002 0
BIRD accepted the route and displayed the AS_PATH with the reserved AS 0 still present.
RFC 7607 Section 2 states that a BGP speaker must not originate or propagate a route with AS number 0 in AS_PATH, and that an UPDATE containing AS number 0 in AS_PATH must be considered malformed and handled according to RFC 7606.
For a malformed AS_PATH attribute with parseable NLRI, RFC 7606 handling should be treat-as-withdraw: the route should not be installed, while the BGP session should remain established. Affected Version
Hello Thanks for the notice, we somehow missed RFC 7607, so we validate AS_PATH just for structural properties according to RFC 7606 section 7.2. We added this (and the other issue with accepting OPEN for ASN 0) to our todo list for the next minor release. -- Elen sila lumenn' omentielvo Ondrej 'Santiago' Zajicek (email: santiago@crfreenet.org) "To err is human -- to blame it on a computer is even more so."
participants (1)
-
Ondrej Zajicek -
xinzhe liu