From a0ee380a409e41cc8b0abaf351be72cd2c658d41 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Tue, 20 Jun 2023 14:53:24 +0200 Subject: [PATCH] bgpd: fix match expanded community with any community A list of communities from an incoming BGP update is never matched against an expanded bgp community-list configured for matching only one of the communities. The below configuration can help: > bgp community-list expanded com1 seq 5 permit ^44 > router bgp 65001 > [..] > route-map r2 permit 10 > match community com1 > set as-path replace 65003 > exit The received '172.16.255.32/32' prefix has a community with '^44', but does not match the route-map rule. Observed dump: > r1# show bgp ipv4 172.16.255.32/32 > BGP routing table entry for 172.16.255.32/32, version 4 > Paths: (1 available, best #1, table default) > Advertised to non peer-group peers: > 192.168.1.2 > 65003 65002 > 192.168.1.2 from 192.168.1.2 (192.0.2.2) > Origin incomplete, valid, external, best (First path received) > Community: 11:11 22:22 33:33 44:44 44:77 44:453 55:55 66:66 > Last update: Tue Jun 20 15:05:27 2023 The route-map rule does not make any differences with and without the 'exact-match' keyword, and does not filter the prefix. Change the behaviour of the route-map rule without exact-match, by applying the regexp to each community of the received community-list. Observed behaviour: > r1# r1# show bgp ipv4 172.16.255.32/32 > BGP routing table entry for 172.16.255.32/32, version 5 > Paths: (1 available, best #1, table default) > Advertised to non peer-group peers: > 192.168.1.2 > 65001 65002 > 192.168.1.2 from 192.168.1.2 (192.0.2.2) > Origin incomplete, valid, external, best (First path received) > Community: 11:11 22:22 33:33 44:44 44:77 44:453 55:55 66:66 > Last update: Tue Jun 20 15:09:55 2023 Signed-off-by: Philippe Guibert --- bgpd/bgp_clist.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_clist.c b/bgpd/bgp_clist.c index f3c308afb9e3..d714469a999b 100644 --- a/bgpd/bgp_clist.c +++ b/bgpd/bgp_clist.c @@ -657,6 +657,7 @@ static bool ecommunity_regexp_match(struct ecommunity *ecom, regex_t *reg) bool community_list_match(struct community *com, struct community_list *list) { struct community_entry *entry; + int i; for (entry = list->head; entry; entry = entry->next) { if (entry->style == COMMUNITY_LIST_STANDARD) { @@ -666,8 +667,10 @@ bool community_list_match(struct community *com, struct community_list *list) if (community_match(com, entry->u.com)) return entry->direct == COMMUNITY_PERMIT; } else if (entry->style == COMMUNITY_LIST_EXPANDED) { - if (community_regexp_match(com, entry->reg)) - return entry->direct == COMMUNITY_PERMIT; + for (i = 0; i < com->size; i++) { + if (community_regexp_include(entry->reg, com, i)) + return entry->direct == COMMUNITY_PERMIT; + } } } return false;