* additional handling to prevent bgp from injecting and holding on to a
* non-best local path.
*/
-static void evpn_cleanup_local_non_best_route(struct bgp *bgp,
- struct bgpevpn *vpn,
- struct bgp_dest *dest,
- struct bgp_path_info *local_pi)
+static struct bgp_dest *
+evpn_cleanup_local_non_best_route(struct bgp *bgp, struct bgpevpn *vpn,
+ struct bgp_dest *dest,
+ struct bgp_path_info *local_pi)
{
/* local path was not picked as the winner; kick it out */
if (bgp_debug_zebra(NULL))
dest);
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 */
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,
} else {
if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
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 {
bool new_is_sync;
}
bgp_path_info_unlock(pi);
- bgp_dest_unlock_node(dest);
+ if (dest)
+ bgp_dest_unlock_node(dest);
/* If this is a new route or some attribute has changed, export the
* route to the global table. The route will be advertised to peers
/* Do the actual removal of info from RIB, for use by bgp_process
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)
pi->next->prev = pi->prev;
bgp_path_info_mpath_dequeue(pi);
bgp_path_info_unlock(pi);
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)
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_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,
struct bgp_path_info *pi);
extern struct bgp_path_info_extra *