From fde0cf6df77de9622b7c6419746018e40c65f7b8 Mon Sep 17 00:00:00 2001 From: Don Slice Date: Thu, 10 Sep 2020 12:40:28 +0000 Subject: [PATCH] bgpd: correct community-list replace logic Problem rerported that if you enter an existing community list sequence number with new community information, the entire community list would be deleted. This commit fixes the replace logic to do the right thing. Ticket: CM-30555 Signed-off-by: Don Slice --- bgpd/bgp_clist.c | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/bgpd/bgp_clist.c b/bgpd/bgp_clist.c index 5b3908442c..247d758f8c 100644 --- a/bgpd/bgp_clist.c +++ b/bgpd/bgp_clist.c @@ -337,18 +337,42 @@ static void community_list_entry_delete(struct community_list_master *cm, community_list_delete(cm, list); } +/* + * Replace community-list entry in the list. Note that entry is the new one + * and replace is one one being replaced. + */ +static void community_list_entry_replace(struct community_list *list, + struct community_entry *replace, + struct community_entry *entry) +{ + if (replace->next) { + entry->next = replace->next; + replace->next->prev = entry; + } else { + entry->next = NULL; + list->tail = entry; + } + + if (replace->prev) { + entry->prev = replace->prev; + replace->prev->next = entry; + } else { + entry->prev = NULL; + list->head = entry; + } + + community_entry_free(replace); +} + /* Add community-list entry to the list. */ static void community_list_entry_add(struct community_list *list, struct community_entry *entry, struct community_list_handler *ch, int master) { - struct community_list_master *cm = NULL; struct community_entry *replace; struct community_entry *point; - cm = community_list_master_lookup(ch, master); - /* Automatic assignment of seq no. */ if (entry->seq == COMMUNITY_SEQ_NUMBER_AUTO) entry->seq = bgp_clist_new_seq_get(list); @@ -357,8 +381,10 @@ static void community_list_entry_add(struct community_list *list, point = NULL; else { replace = bgp_clist_seq_check(list, entry->seq); - if (replace) - community_list_entry_delete(cm, list, entry); + if (replace) { + community_list_entry_replace(list, replace, entry); + return; + } /* Check insert point. */ for (point = list->head; point; point = point->next) -- 2.39.5