]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: correct community-list replace logic
authorDon Slice <dslice@nvidia.com>
Thu, 10 Sep 2020 12:40:28 +0000 (12:40 +0000)
committerDon Slice <dslice@nvidia.com>
Sat, 12 Sep 2020 13:17:32 +0000 (06:17 -0700)
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 <dslice@nvidia.com>
bgpd/bgp_clist.c

index 5b3908442cad1b22bfdc9c02ef9126537338fa7a..247d758f8cd6b7232946b81c807c5817d3aa3d46 100644 (file)
@@ -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)