mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-28 15:36:25 +00:00
lib : fix duplicate prefix list delete
Problem statement: Step-1: pl1 - 10.10.10.10/24 with deny sequence 1 Step-2: pl1 - 10.10.10.10/24 with permit sequence 2 Step-3: pl1 - 20.20.20.20/24 with deny sequence 1 Now we end up deleting permit sequence 2, which might blackhole the traffic. RCA: Whenever we have multiple prefix lists, having same prefix and different subnet range, delete or replace of prefix list would result in delete of entry in route-map prefix table. Fix: We will skip deleting prefix list entry from routemap prefix table, if we have the multiple prefix lists having same prefix. Signed-off-by: Samanvitha B Bhargav <bsamanvitha@vmware.com>
This commit is contained in:
parent
25664eae52
commit
394ed767e7
39
lib/plist.c
39
lib/plist.c
@ -336,6 +336,22 @@ prefix_list_entry_lookup(struct prefix_list *plist, struct prefix *prefix,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
prefix_list_entry_lookup_prefix(struct prefix_list *plist,
|
||||||
|
struct prefix_list_entry *plist_entry)
|
||||||
|
{
|
||||||
|
struct prefix_list_entry *pentry = NULL;
|
||||||
|
|
||||||
|
for (pentry = plist->head; pentry; pentry = pentry->next) {
|
||||||
|
if (pentry == plist_entry)
|
||||||
|
continue;
|
||||||
|
if (prefix_same(&pentry->prefix, &plist_entry->prefix))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static void trie_walk_affected(size_t validbits, struct pltrie_table *table,
|
static void trie_walk_affected(size_t validbits, struct pltrie_table *table,
|
||||||
uint8_t byte, struct prefix_list_entry *object,
|
uint8_t byte, struct prefix_list_entry *object,
|
||||||
void (*fn)(struct prefix_list_entry *object,
|
void (*fn)(struct prefix_list_entry *object,
|
||||||
@ -404,12 +420,16 @@ static void prefix_list_trie_del(struct prefix_list *plist,
|
|||||||
|
|
||||||
|
|
||||||
void prefix_list_entry_delete(struct prefix_list *plist,
|
void prefix_list_entry_delete(struct prefix_list *plist,
|
||||||
struct prefix_list_entry *pentry,
|
struct prefix_list_entry *pentry, int update_list)
|
||||||
int update_list)
|
|
||||||
{
|
{
|
||||||
|
bool duplicate = false;
|
||||||
|
|
||||||
if (plist == NULL || pentry == NULL)
|
if (plist == NULL || pentry == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (prefix_list_entry_lookup_prefix(plist, pentry))
|
||||||
|
duplicate = true;
|
||||||
|
|
||||||
prefix_list_trie_del(plist, pentry);
|
prefix_list_trie_del(plist, pentry);
|
||||||
|
|
||||||
if (pentry->prev)
|
if (pentry->prev)
|
||||||
@ -421,8 +441,10 @@ void prefix_list_entry_delete(struct prefix_list *plist,
|
|||||||
else
|
else
|
||||||
plist->tail = pentry->prev;
|
plist->tail = pentry->prev;
|
||||||
|
|
||||||
route_map_notify_pentry_dependencies(plist->name, pentry,
|
if (!duplicate)
|
||||||
RMAP_EVENT_PLIST_DELETED);
|
route_map_notify_pentry_dependencies(plist->name, pentry,
|
||||||
|
RMAP_EVENT_PLIST_DELETED);
|
||||||
|
|
||||||
prefix_list_entry_free(pentry);
|
prefix_list_entry_free(pentry);
|
||||||
|
|
||||||
plist->count--;
|
plist->count--;
|
||||||
@ -557,11 +579,15 @@ static void prefix_list_entry_add(struct prefix_list *plist,
|
|||||||
void prefix_list_entry_update_start(struct prefix_list_entry *ple)
|
void prefix_list_entry_update_start(struct prefix_list_entry *ple)
|
||||||
{
|
{
|
||||||
struct prefix_list *pl = ple->pl;
|
struct prefix_list *pl = ple->pl;
|
||||||
|
bool duplicate = false;
|
||||||
|
|
||||||
/* Not installed, nothing to do. */
|
/* Not installed, nothing to do. */
|
||||||
if (!ple->installed)
|
if (!ple->installed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (prefix_list_entry_lookup_prefix(pl, ple))
|
||||||
|
duplicate = true;
|
||||||
|
|
||||||
prefix_list_trie_del(pl, ple);
|
prefix_list_trie_del(pl, ple);
|
||||||
|
|
||||||
/* List manipulation: shameless copy from `prefix_list_entry_delete`. */
|
/* List manipulation: shameless copy from `prefix_list_entry_delete`. */
|
||||||
@ -574,8 +600,9 @@ void prefix_list_entry_update_start(struct prefix_list_entry *ple)
|
|||||||
else
|
else
|
||||||
pl->tail = ple->prev;
|
pl->tail = ple->prev;
|
||||||
|
|
||||||
route_map_notify_pentry_dependencies(pl->name, ple,
|
if (!duplicate)
|
||||||
RMAP_EVENT_PLIST_DELETED);
|
route_map_notify_pentry_dependencies(pl->name, ple,
|
||||||
|
RMAP_EVENT_PLIST_DELETED);
|
||||||
pl->count--;
|
pl->count--;
|
||||||
|
|
||||||
route_map_notify_dependencies(pl->name, RMAP_EVENT_PLIST_DELETED);
|
route_map_notify_dependencies(pl->name, RMAP_EVENT_PLIST_DELETED);
|
||||||
|
Loading…
Reference in New Issue
Block a user