See https://github.com/openbgpd-portable/openbgpd-portable/issues/64
The handling of non-transitive ext communities causes encoding errors in
for regular communities. The problem is that the start and end points of
the loop are calculated like this:
for (l = 0; l < comm->nentries; l++) {
cp = &comm->communities[l];
if (ebgp && non_transitive_ext_community(cp))
continue;
if ((uint8_t)cp->flags == t) {
num++;
if (start == -1)
start = l;
}
if ((uint8_t)cp->flags > t)
break;
}
end = l;
But in the write out loop the non_transitive_ext_community() check
is only done inside the ext-community block. As a result
COMMUNITY_TYPE_BASIC communities can walk over their respective end of the
list into the COMMUNITY_TYPE_EXT communities (if the non-transitive
ext-comm is the first ext-community).
The fix is to move the non_transitive_ext_community() check into
if ((uint8_t)cp->flags == t) { } block. Since then we know the type is
correct.
--
:wq Claudio
Index: rde_community.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde_community.c,v
retrieving revision 1.13
diff -u -p -r1.13 rde_community.c
--- rde_community.c 12 Jul 2023 14:45:43 -0000 1.13
+++ rde_community.c 10 Oct 2023 13:43:03 -0000
@@ -556,10 +556,9 @@ community_writebuf(struct rde_community
start = -1;
for (l = 0; l < comm->nentries; l++) {
cp = &comm->communities[l];
-
- if (ebgp && non_transitive_ext_community(cp))
- continue;
if ((uint8_t)cp->flags == t) {
+ if (ebgp && non_transitive_ext_community(cp))
+ continue;
num++;
if (start == -1)
start = l;