The bird extended community construct (kind, key, value) is mapped to a 64 bit extended community value in one of three possible ways. kind = rt/ro/numeric, key <= 0xffff ("RFC 4360 3.1. Two-Octet AS Specific Extended Community"): +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | kind | key | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | value | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ kind = rt/ro/numeric, key >= 0x10000 ("RFC 5668 4-Octet AS Specific BGP Extended Community"): +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | kind | key (upper half) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | key (lower half) | value | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ kind = generic: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | key | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | value | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ filter/config.Y:f_new_ec_item() currently clamps the value part to 0..0xffff whenever key >= 0x10000, which makes sense if key and value together need to fit into 48 bits, but this is not the case for generic extended communities, and performing the clamping for generic extended communities is incorrect. diff --git a/filter/config.Y b/filter/config.Y index 56ef598..370159a 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -112,7 +112,7 @@ f_new_ec_item(u32 kind, u32 ipv4_used, u32 key, u32 vf, u32 vt) { u64 fm, to; - if (ipv4_used || (key >= 0x10000)) { + if (ipv4_used || (kind != EC_GENERIC && key >= 0x10000)) { check_u16(vf); if (vt == EC_ALL) vt = 0xFFFF;