diff --git a/lib/routemap.c b/lib/routemap.c index 9afe18d10b..46161fd817 100644 --- a/lib/routemap.c +++ b/lib/routemap.c @@ -100,6 +100,7 @@ static void route_map_del_plist_entries(afi_t afi, struct prefix_list_entry *entry); static struct hash *route_map_get_dep_hash(route_map_event_t event); +static void route_map_free_map(struct route_map *map); struct route_map_match_set_hooks rmap_match_set_hook; @@ -566,15 +567,8 @@ static bool route_map_hash_cmp(const void *p1, const void *p2) const struct route_map *map1 = p1; const struct route_map *map2 = p2; - if (map1->deleted == map2->deleted) { - if (map1->name && map2->name) { - if (!strcmp(map1->name, map2->name)) { - return true; - } - } else if (!map1->name && !map2->name) { - return true; - } - } + if (!strcmp(map1->name, map2->name)) + return true; return false; } @@ -636,13 +630,25 @@ static struct route_map *route_map_new(const char *name) /* Add new name to route_map. */ static struct route_map *route_map_add(const char *name) { - struct route_map *map; + struct route_map *map, *exist; struct route_map_list *list; map = route_map_new(name); list = &route_map_master; - /* Add map to the hash */ + /* + * Add map to the hash + * + * If the map already exists in the hash, then we know that + * FRR is now in a sequence of delete/create. + * All FRR needs to do here is set the to_be_processed + * bit (to inherit from the old one + */ + exist = hash_release(route_map_master_hash, map); + if (exist) { + map->to_be_processed = exist->to_be_processed; + route_map_free_map(exist); + } hash_get(route_map_master_hash, map, hash_alloc_intern); /* Add new entry to the head of the list to match how it is added in the @@ -752,11 +758,15 @@ struct route_map *route_map_lookup_by_name(const char *name) if (!name) return NULL; - // map.deleted is 0 via memset + // map.deleted is false via memset memset(&tmp_map, 0, sizeof(struct route_map)); tmp_map.name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, name); map = hash_lookup(route_map_master_hash, &tmp_map); XFREE(MTYPE_ROUTE_MAP_NAME, tmp_map.name); + + if (map && map->deleted) + return NULL; + return map; }