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.
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 0BIRD 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.
I reproduced this on:
BIRD version 2.19.0+branch.master.880200b1f94c
commit 880200b1After 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/24BIRD 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: 100The 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 0I 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 ...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:
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.
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.
Accepting AS 0 in AS_PATH can cause interoperability and policy issues:
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