mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-15 09:20:25 +00:00
bgpd: evpn_cleanup_local_non_best_route could free dest
But never really does due to locking, but since it can we need to treat it like it does and ensure that FRR is not making a mistake, by using memory after it has been freed. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
This commit is contained in:
parent
ec8a02af45
commit
b45925ad10
@ -2035,8 +2035,8 @@ static void evpn_zebra_reinstall_best_route(struct bgp *bgp,
|
|||||||
* additional handling to prevent bgp from injecting and holding on to a
|
* additional handling to prevent bgp from injecting and holding on to a
|
||||||
* non-best local path.
|
* non-best local path.
|
||||||
*/
|
*/
|
||||||
static void evpn_cleanup_local_non_best_route(struct bgp *bgp,
|
static struct bgp_dest *
|
||||||
struct bgpevpn *vpn,
|
evpn_cleanup_local_non_best_route(struct bgp *bgp, struct bgpevpn *vpn,
|
||||||
struct bgp_dest *dest,
|
struct bgp_dest *dest,
|
||||||
struct bgp_path_info *local_pi)
|
struct bgp_path_info *local_pi)
|
||||||
{
|
{
|
||||||
@ -2046,10 +2046,11 @@ static void evpn_cleanup_local_non_best_route(struct bgp *bgp,
|
|||||||
dest);
|
dest);
|
||||||
|
|
||||||
evpn_delete_old_local_route(bgp, vpn, dest, local_pi, NULL);
|
evpn_delete_old_local_route(bgp, vpn, dest, local_pi, NULL);
|
||||||
bgp_path_info_reap(dest, local_pi);
|
|
||||||
|
|
||||||
/* tell zebra to re-add the best remote path */
|
/* tell zebra to re-add the best remote path */
|
||||||
evpn_zebra_reinstall_best_route(bgp, vpn, dest);
|
evpn_zebra_reinstall_best_route(bgp, vpn, dest);
|
||||||
|
|
||||||
|
return bgp_path_info_reap(dest, local_pi);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool bgp_evpn_route_add_l3_ecomm_ok(struct bgpevpn *vpn,
|
static inline bool bgp_evpn_route_add_l3_ecomm_ok(struct bgpevpn *vpn,
|
||||||
@ -2186,7 +2187,8 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
|
|||||||
} else {
|
} else {
|
||||||
if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
|
if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
|
||||||
route_change = 0;
|
route_change = 0;
|
||||||
evpn_cleanup_local_non_best_route(bgp, vpn, dest, pi);
|
dest = evpn_cleanup_local_non_best_route(bgp, vpn, dest,
|
||||||
|
pi);
|
||||||
} else {
|
} else {
|
||||||
bool new_is_sync;
|
bool new_is_sync;
|
||||||
|
|
||||||
@ -2203,6 +2205,7 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
|
|||||||
}
|
}
|
||||||
bgp_path_info_unlock(pi);
|
bgp_path_info_unlock(pi);
|
||||||
|
|
||||||
|
if (dest)
|
||||||
bgp_dest_unlock_node(dest);
|
bgp_dest_unlock_node(dest);
|
||||||
|
|
||||||
/* If this is a new route or some attribute has changed, export the
|
/* If this is a new route or some attribute has changed, export the
|
||||||
|
@ -438,7 +438,8 @@ void bgp_path_info_add_with_caller(const char *name, struct bgp_dest *dest,
|
|||||||
|
|
||||||
/* Do the actual removal of info from RIB, for use by bgp_process
|
/* Do the actual removal of info from RIB, for use by bgp_process
|
||||||
completion callback *only* */
|
completion callback *only* */
|
||||||
void bgp_path_info_reap(struct bgp_dest *dest, struct bgp_path_info *pi)
|
struct bgp_dest *bgp_path_info_reap(struct bgp_dest *dest,
|
||||||
|
struct bgp_path_info *pi)
|
||||||
{
|
{
|
||||||
if (pi->next)
|
if (pi->next)
|
||||||
pi->next->prev = pi->prev;
|
pi->next->prev = pi->prev;
|
||||||
@ -450,7 +451,8 @@ void bgp_path_info_reap(struct bgp_dest *dest, struct bgp_path_info *pi)
|
|||||||
bgp_path_info_mpath_dequeue(pi);
|
bgp_path_info_mpath_dequeue(pi);
|
||||||
bgp_path_info_unlock(pi);
|
bgp_path_info_unlock(pi);
|
||||||
hook_call(bgp_snmp_update_stats, dest, pi, false);
|
hook_call(bgp_snmp_update_stats, dest, pi, false);
|
||||||
bgp_dest_unlock_node(dest);
|
|
||||||
|
return bgp_dest_unlock_node(dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bgp_path_info_delete(struct bgp_dest *dest, struct bgp_path_info *pi)
|
void bgp_path_info_delete(struct bgp_dest *dest, struct bgp_path_info *pi)
|
||||||
|
@ -727,7 +727,8 @@ extern struct bgp_path_info *
|
|||||||
bgp_get_imported_bpi_ultimate(struct bgp_path_info *info);
|
bgp_get_imported_bpi_ultimate(struct bgp_path_info *info);
|
||||||
extern void bgp_path_info_add(struct bgp_dest *dest, struct bgp_path_info *pi);
|
extern void bgp_path_info_add(struct bgp_dest *dest, struct bgp_path_info *pi);
|
||||||
extern void bgp_path_info_extra_free(struct bgp_path_info_extra **extra);
|
extern void bgp_path_info_extra_free(struct bgp_path_info_extra **extra);
|
||||||
extern void bgp_path_info_reap(struct bgp_dest *dest, struct bgp_path_info *pi);
|
extern struct bgp_dest *bgp_path_info_reap(struct bgp_dest *dest,
|
||||||
|
struct bgp_path_info *pi);
|
||||||
extern void bgp_path_info_delete(struct bgp_dest *dest,
|
extern void bgp_path_info_delete(struct bgp_dest *dest,
|
||||||
struct bgp_path_info *pi);
|
struct bgp_path_info *pi);
|
||||||
extern struct bgp_path_info_extra *
|
extern struct bgp_path_info_extra *
|
||||||
|
Loading…
Reference in New Issue
Block a user