mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 16:04:49 +00:00
zebra: remove useless deleted route_entries promptly
Zebra accumulates route-entry objects and then processes them as a group. If that rib processing is delayed, because the dataplane/fib programming has built up a queue e.g., zebra can hold multiple deleted route objects in memory. At scale, this can be a problem. Delete unneeded route entries promptly, if they can't contribute to rib processing. Signed-off-by: Mark Stapp <mjs@voltanet.io>
This commit is contained in:
parent
e8678e2c51
commit
0ca6f3b1e6
@ -2933,8 +2933,10 @@ int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p,
|
|||||||
struct nhg_hash_entry *nhe = NULL;
|
struct nhg_hash_entry *nhe = NULL;
|
||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
struct route_entry *same = NULL;
|
struct route_entry *same = NULL, *first_same = NULL;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
int same_count = 0;
|
||||||
|
rib_dest_t *dest;
|
||||||
|
|
||||||
if (!re || !re_nhe)
|
if (!re || !re_nhe)
|
||||||
return -1;
|
return -1;
|
||||||
@ -3002,14 +3004,22 @@ int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p,
|
|||||||
* for the install don't do a route replace.
|
* for the install don't do a route replace.
|
||||||
*/
|
*/
|
||||||
RNODE_FOREACH_RE (rn, same) {
|
RNODE_FOREACH_RE (rn, same) {
|
||||||
if (CHECK_FLAG(same->status, ROUTE_ENTRY_REMOVED))
|
if (CHECK_FLAG(same->status, ROUTE_ENTRY_REMOVED)) {
|
||||||
|
same_count++;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* Compare various route_entry properties */
|
/* Compare various route_entry properties */
|
||||||
if (rib_compare_routes(re, same))
|
if (rib_compare_routes(re, same)) {
|
||||||
break;
|
same_count++;
|
||||||
|
|
||||||
|
if (first_same == NULL)
|
||||||
|
first_same = same;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
same = first_same;
|
||||||
|
|
||||||
/* If this route is kernel/connected route, notify the dataplane. */
|
/* If this route is kernel/connected route, notify the dataplane. */
|
||||||
if (RIB_SYSTEM_ROUTE(re)) {
|
if (RIB_SYSTEM_ROUTE(re)) {
|
||||||
/* Notify dataplane */
|
/* Notify dataplane */
|
||||||
@ -3019,8 +3029,9 @@ int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p,
|
|||||||
/* Link new re to node.*/
|
/* Link new re to node.*/
|
||||||
if (IS_ZEBRA_DEBUG_RIB) {
|
if (IS_ZEBRA_DEBUG_RIB) {
|
||||||
rnode_debug(rn, re->vrf_id,
|
rnode_debug(rn, re->vrf_id,
|
||||||
"Inserting route rn %p, re %p (%s) existing %p",
|
"Inserting route rn %p, re %p (%s) existing %p, same_count %d",
|
||||||
rn, re, zebra_route_string(re->type), same);
|
rn, re, zebra_route_string(re->type), same,
|
||||||
|
same_count);
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
||||||
route_entry_dump(p, src_p, re);
|
route_entry_dump(p, src_p, re);
|
||||||
@ -3034,6 +3045,24 @@ int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p,
|
|||||||
if (same)
|
if (same)
|
||||||
rib_delnode(rn, same);
|
rib_delnode(rn, same);
|
||||||
|
|
||||||
|
/* See if we can remove some RE entries that are queued for
|
||||||
|
* removal, but won't be considered in rib processing.
|
||||||
|
*/
|
||||||
|
dest = rib_dest_from_rnode(rn);
|
||||||
|
RNODE_FOREACH_RE_SAFE (rn, re, same) {
|
||||||
|
if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED)) {
|
||||||
|
/* If the route was used earlier, must retain it. */
|
||||||
|
if (dest && re == dest->selected_fib)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (IS_ZEBRA_DEBUG_RIB)
|
||||||
|
rnode_debug(rn, re->vrf_id, "rn %p, removing unneeded re %p",
|
||||||
|
rn, re);
|
||||||
|
|
||||||
|
rib_unlink(rn, re);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
route_unlock_node(rn);
|
route_unlock_node(rn);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user