mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-08 12:49:18 +00:00
lib: fix prefix list installation
Based on the function `prefix_list_entry_add` and `prefix_list_entry_delete` it was created two functions to replicate its functionality without the assumption we are always alocating a new prefix list entry. Since the prefix list entry is stored in the YANG private data structures, we want to avoid the allocation/free of memory that is hold by the schema. Every time a prefix list entry values change we must call `prefix_list_entry_update_start` to uninstall the entry from prefix list internal structures and then call `prefix_list_entry_update_finish` to put them back. The variable `installed` in the prefix list entry tracks the installation status of the internal structure. It is possible that a user unconfigures or forgets to add a `prefix` value and so we can't install the entry until then. Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
This commit is contained in:
parent
25ceb5d807
commit
a7b2821884
@ -838,6 +838,7 @@ static int lib_prefix_list_entry_create(struct nb_cb_create_args *args)
|
|||||||
ple->pl = pl;
|
ple->pl = pl;
|
||||||
ple->any = 1;
|
ple->any = 1;
|
||||||
ple->seq = yang_dnode_get_uint32(args->dnode, "./sequence");
|
ple->seq = yang_dnode_get_uint32(args->dnode, "./sequence");
|
||||||
|
nb_running_set_entry(args->dnode, ple);
|
||||||
|
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
@ -850,7 +851,10 @@ static int lib_prefix_list_entry_destroy(struct nb_cb_destroy_args *args)
|
|||||||
return NB_OK;
|
return NB_OK;
|
||||||
|
|
||||||
ple = nb_running_unset_entry(args->dnode);
|
ple = nb_running_unset_entry(args->dnode);
|
||||||
prefix_list_entry_delete(ple->pl, ple, 1);
|
if (ple->installed)
|
||||||
|
prefix_list_entry_delete(ple->pl, ple, 0);
|
||||||
|
else
|
||||||
|
prefix_list_entry_free(ple);
|
||||||
|
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
@ -867,12 +871,19 @@ static int lib_prefix_list_entry_action_modify(struct nb_cb_modify_args *args)
|
|||||||
return NB_OK;
|
return NB_OK;
|
||||||
|
|
||||||
ple = nb_running_get_entry(args->dnode, NULL, true);
|
ple = nb_running_get_entry(args->dnode, NULL, true);
|
||||||
|
|
||||||
|
/* Start prefix entry update procedure. */
|
||||||
|
prefix_list_entry_update_start(ple);
|
||||||
|
|
||||||
action_str = yang_dnode_get_string(args->dnode, NULL);
|
action_str = yang_dnode_get_string(args->dnode, NULL);
|
||||||
if (strcmp(action_str, "permit") == 0)
|
if (strcmp(action_str, "permit") == 0)
|
||||||
ple->type = PREFIX_PERMIT;
|
ple->type = PREFIX_PERMIT;
|
||||||
else
|
else
|
||||||
ple->type = PREFIX_DENY;
|
ple->type = PREFIX_DENY;
|
||||||
|
|
||||||
|
/* Finish prefix entry update procedure. */
|
||||||
|
prefix_list_entry_update_finish(ple);
|
||||||
|
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -888,8 +899,15 @@ lib_prefix_list_entry_ipv4_prefix_modify(struct nb_cb_modify_args *args)
|
|||||||
return NB_OK;
|
return NB_OK;
|
||||||
|
|
||||||
ple = nb_running_get_entry(args->dnode, NULL, true);
|
ple = nb_running_get_entry(args->dnode, NULL, true);
|
||||||
|
|
||||||
|
/* Start prefix entry update procedure. */
|
||||||
|
prefix_list_entry_update_start(ple);
|
||||||
|
|
||||||
yang_dnode_get_prefix(&ple->prefix, args->dnode, NULL);
|
yang_dnode_get_prefix(&ple->prefix, args->dnode, NULL);
|
||||||
|
|
||||||
|
/* Finish prefix entry update procedure. */
|
||||||
|
prefix_list_entry_update_finish(ple);
|
||||||
|
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -902,9 +920,16 @@ lib_prefix_list_entry_ipv4_prefix_destroy(struct nb_cb_destroy_args *args)
|
|||||||
return NB_OK;
|
return NB_OK;
|
||||||
|
|
||||||
ple = nb_running_get_entry(args->dnode, NULL, true);
|
ple = nb_running_get_entry(args->dnode, NULL, true);
|
||||||
|
|
||||||
|
/* Start prefix entry update procedure. */
|
||||||
|
prefix_list_entry_update_start(ple);
|
||||||
|
|
||||||
memset(&ple->prefix, 0, sizeof(ple->prefix));
|
memset(&ple->prefix, 0, sizeof(ple->prefix));
|
||||||
ple->any = 1;
|
ple->any = 1;
|
||||||
|
|
||||||
|
/* Finish prefix entry update procedure. */
|
||||||
|
prefix_list_entry_update_finish(ple);
|
||||||
|
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -924,8 +949,15 @@ static int lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_modify(
|
|||||||
return NB_OK;
|
return NB_OK;
|
||||||
|
|
||||||
ple = nb_running_get_entry(args->dnode, NULL, true);
|
ple = nb_running_get_entry(args->dnode, NULL, true);
|
||||||
|
|
||||||
|
/* Start prefix entry update procedure. */
|
||||||
|
prefix_list_entry_update_start(ple);
|
||||||
|
|
||||||
ple->ge = yang_dnode_get_uint8(args->dnode, NULL);
|
ple->ge = yang_dnode_get_uint8(args->dnode, NULL);
|
||||||
|
|
||||||
|
/* Finish prefix entry update procedure. */
|
||||||
|
prefix_list_entry_update_finish(ple);
|
||||||
|
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -938,8 +970,15 @@ static int lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_destroy(
|
|||||||
return NB_OK;
|
return NB_OK;
|
||||||
|
|
||||||
ple = nb_running_get_entry(args->dnode, NULL, true);
|
ple = nb_running_get_entry(args->dnode, NULL, true);
|
||||||
|
|
||||||
|
/* Start prefix entry update procedure. */
|
||||||
|
prefix_list_entry_update_start(ple);
|
||||||
|
|
||||||
ple->ge = 0;
|
ple->ge = 0;
|
||||||
|
|
||||||
|
/* Finish prefix entry update procedure. */
|
||||||
|
prefix_list_entry_update_finish(ple);
|
||||||
|
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -959,8 +998,15 @@ static int lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_modify(
|
|||||||
return NB_OK;
|
return NB_OK;
|
||||||
|
|
||||||
ple = nb_running_get_entry(args->dnode, NULL, true);
|
ple = nb_running_get_entry(args->dnode, NULL, true);
|
||||||
|
|
||||||
|
/* Start prefix entry update procedure. */
|
||||||
|
prefix_list_entry_update_start(ple);
|
||||||
|
|
||||||
ple->le = yang_dnode_get_uint8(args->dnode, NULL);
|
ple->le = yang_dnode_get_uint8(args->dnode, NULL);
|
||||||
|
|
||||||
|
/* Finish prefix entry update procedure. */
|
||||||
|
prefix_list_entry_update_finish(ple);
|
||||||
|
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -973,8 +1019,15 @@ static int lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_destroy(
|
|||||||
return NB_OK;
|
return NB_OK;
|
||||||
|
|
||||||
ple = nb_running_get_entry(args->dnode, NULL, true);
|
ple = nb_running_get_entry(args->dnode, NULL, true);
|
||||||
|
|
||||||
|
/* Start prefix entry update procedure. */
|
||||||
|
prefix_list_entry_update_start(ple);
|
||||||
|
|
||||||
ple->le = 0;
|
ple->le = 0;
|
||||||
|
|
||||||
|
/* Finish prefix entry update procedure. */
|
||||||
|
prefix_list_entry_update_finish(ple);
|
||||||
|
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1038,9 +1091,16 @@ static int lib_prefix_list_entry_any_create(struct nb_cb_create_args *args)
|
|||||||
return NB_OK;
|
return NB_OK;
|
||||||
|
|
||||||
ple = nb_running_get_entry(args->dnode, NULL, true);
|
ple = nb_running_get_entry(args->dnode, NULL, true);
|
||||||
|
|
||||||
|
/* Start prefix entry update procedure. */
|
||||||
|
prefix_list_entry_update_start(ple);
|
||||||
|
|
||||||
memset(&ple->prefix, 0, sizeof(ple->prefix));
|
memset(&ple->prefix, 0, sizeof(ple->prefix));
|
||||||
ple->any = 1;
|
ple->any = 1;
|
||||||
|
|
||||||
|
/* Finish prefix entry update procedure. */
|
||||||
|
prefix_list_entry_update_finish(ple);
|
||||||
|
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1052,9 +1112,16 @@ static int lib_prefix_list_entry_any_destroy(struct nb_cb_destroy_args *args)
|
|||||||
return NB_OK;
|
return NB_OK;
|
||||||
|
|
||||||
ple = nb_running_get_entry(args->dnode, NULL, true);
|
ple = nb_running_get_entry(args->dnode, NULL, true);
|
||||||
|
|
||||||
|
/* Start prefix entry update procedure. */
|
||||||
|
prefix_list_entry_update_start(ple);
|
||||||
|
|
||||||
memset(&ple->prefix, 0, sizeof(ple->prefix));
|
memset(&ple->prefix, 0, sizeof(ple->prefix));
|
||||||
ple->any = 1;
|
ple->any = 1;
|
||||||
|
|
||||||
|
/* Finish prefix entry update procedure. */
|
||||||
|
prefix_list_entry_update_finish(ple);
|
||||||
|
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
54
lib/plist.c
54
lib/plist.c
@ -187,7 +187,7 @@ struct prefix_list_entry *prefix_list_entry_new(void)
|
|||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void prefix_list_entry_free(struct prefix_list_entry *pentry)
|
void prefix_list_entry_free(struct prefix_list_entry *pentry)
|
||||||
{
|
{
|
||||||
XFREE(MTYPE_PREFIX_LIST_ENTRY, pentry);
|
XFREE(MTYPE_PREFIX_LIST_ENTRY, pentry);
|
||||||
}
|
}
|
||||||
@ -646,6 +646,58 @@ static void prefix_list_entry_add(struct prefix_list *plist,
|
|||||||
plist->master->recent = plist;
|
plist->master->recent = plist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prefix list entry update start procedure:
|
||||||
|
* Remove entry from previosly installed tries and notify observers..
|
||||||
|
*
|
||||||
|
* \param[in] ple prefix list entry.
|
||||||
|
*/
|
||||||
|
void prefix_list_entry_update_start(struct prefix_list_entry *ple)
|
||||||
|
{
|
||||||
|
struct prefix_list *pl = ple->pl;
|
||||||
|
|
||||||
|
/* Not installed, nothing to do. */
|
||||||
|
if (!ple->installed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
prefix_list_trie_del(pl, ple);
|
||||||
|
route_map_notify_pentry_dependencies(pl->name, ple,
|
||||||
|
RMAP_EVENT_PLIST_DELETED);
|
||||||
|
pl->count--;
|
||||||
|
|
||||||
|
ple->installed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prefix list entry update finish procedure:
|
||||||
|
* Add entry back to trie, notify observers and call master hook.
|
||||||
|
*
|
||||||
|
* \param[in] ple prefix list entry.
|
||||||
|
*/
|
||||||
|
void prefix_list_entry_update_finish(struct prefix_list_entry *ple)
|
||||||
|
{
|
||||||
|
struct prefix_list *pl = ple->pl;
|
||||||
|
|
||||||
|
/* Already installed, nothing to do. */
|
||||||
|
if (ple->installed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
prefix_list_trie_add(pl, ple);
|
||||||
|
pl->count++;
|
||||||
|
|
||||||
|
route_map_notify_pentry_dependencies(pl->name, ple,
|
||||||
|
RMAP_EVENT_PLIST_ADDED);
|
||||||
|
|
||||||
|
/* Run hook function. */
|
||||||
|
if (pl->master->add_hook)
|
||||||
|
(*pl->master->add_hook)(pl);
|
||||||
|
|
||||||
|
route_map_notify_dependencies(pl->name, RMAP_EVENT_PLIST_ADDED);
|
||||||
|
pl->master->recent = pl;
|
||||||
|
|
||||||
|
ple->installed = true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Return string of prefix_list_type. */
|
/* Return string of prefix_list_type. */
|
||||||
static const char *prefix_list_type_str(struct prefix_list_entry *pentry)
|
static const char *prefix_list_type_str(struct prefix_list_entry *pentry)
|
||||||
{
|
{
|
||||||
|
@ -72,8 +72,15 @@ struct prefix_list_entry {
|
|||||||
|
|
||||||
/* up the chain for best match search */
|
/* up the chain for best match search */
|
||||||
struct prefix_list_entry *next_best;
|
struct prefix_list_entry *next_best;
|
||||||
|
|
||||||
|
/* Flag to track trie/list installation status. */
|
||||||
|
bool installed;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern void prefix_list_entry_free(struct prefix_list_entry *pentry);
|
||||||
|
extern void prefix_list_entry_update_start(struct prefix_list_entry *ple);
|
||||||
|
extern void prefix_list_entry_update_finish(struct prefix_list_entry *ple);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user