IPv6 address classification
lex
lex at lynx.kwaaknet.org
Thu Jun 9 15:14:46 CEST 2011
bird6 has a rather limited list of IPv6 address classifications, unfortunately limiting the routes that it will accept.
ipv6_classify(ip_addr *a) in lib/ipv6.c:
if ((x & 0xe0000000) == 0x20000000) /* 2000::/3 Aggregatable Global Unicast Address */
if ((x & 0xffc00000) == 0xfe800000) /* fe80::/10 Link-Local Address */
if ((x & 0xffc00000) == 0xfec00000) /* fec0::/10 Site-Local Address */
if ((x & 0xfe000000) == 0xfc000000) /* fc00::/7 Unique Local Unicast Address (RFC 4193) */
if ((x & 0xff000000) == 0xff000000) /* ff00::/8 Multicast Address */
Unfortunately there is a bad side-effect when a BGP peer sends a route for an address that does not fit any of these classifications; bird6 claims that they are "bogus routes", and then seems to drop any routes that have already been received by that peer.
This problem can be very easily reproduced in bird6-1.3.1 by receiving a route outside of these ranges. The validation code appears below, and the problem can be very easily corrected by commenting it out:
rte_validate(rte *e) in nest/rt-table.c:
c = ipa_classify_net(n->n.prefix);
if ((c < 0) || !(c & IADDR_HOST) || ((c & IADDR_SCOPE_MASK) <= SCOPE_LINK))
{
log(L_WARN "Ignoring bogus route %I/%d received via %s",
n->n.prefix, n->n.pxlen, e->sender->name);
return 0;
}
I am interested to hear whether the strictness of the ipv6_classify(ip_addr *a) function would be considered a "bug" or a "feature", but from what I can tell, quagga and openbgpd do not classify addresses in such a strict fashion, and this can produce problems in mixed environments where quagga/openbgpd peers may try and send such routes to bird6.
Perhaps any address that is not link-scoped should be implicitly classified as global? At the very least, receiving a "bogus route" should not result in all existing routes from that peer being dropped.
More information about the Bird-users
mailing list