mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 18:01:54 +00:00
Merge pull request #9321 from donaldsharp/no_leak_re
zebra: Prevent memory leak if route is rejected early
This commit is contained in:
commit
bdb7b7c5d9
@ -403,6 +403,11 @@ extern int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
|
||||
extern int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
|
||||
struct prefix_ipv6 *src_p, struct route_entry *re,
|
||||
struct nexthop_group *ng);
|
||||
/*
|
||||
* -1 -> some sort of error
|
||||
* 0 -> an add
|
||||
* 1 -> an update
|
||||
*/
|
||||
extern int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p,
|
||||
struct prefix_ipv6 *src_p,
|
||||
struct route_entry *re,
|
||||
|
@ -2110,6 +2110,15 @@ static void zread_route_add(ZAPI_HANDLER_ARGS)
|
||||
ret = rib_add_multipath_nhe(afi, api.safi, &api.prefix, src_p,
|
||||
re, &nhe);
|
||||
|
||||
/*
|
||||
* rib_add_multipath_nhe only fails in a couple spots
|
||||
* and in those spots we have not freed memory
|
||||
*/
|
||||
if (ret == -1) {
|
||||
client->error_cnt++;
|
||||
XFREE(MTYPE_RE, re);
|
||||
}
|
||||
|
||||
/* At this point, these allocations are not needed: 're' has been
|
||||
* retained or freed, and if 're' still exists, it is using
|
||||
* a reference to a shared group object.
|
||||
@ -2121,15 +2130,15 @@ static void zread_route_add(ZAPI_HANDLER_ARGS)
|
||||
/* Stats */
|
||||
switch (api.prefix.family) {
|
||||
case AF_INET:
|
||||
if (ret > 0)
|
||||
if (ret == 0)
|
||||
client->v4_route_add_cnt++;
|
||||
else if (ret < 0)
|
||||
else if (ret == 1)
|
||||
client->v4_route_upd8_cnt++;
|
||||
break;
|
||||
case AF_INET6:
|
||||
if (ret > 0)
|
||||
if (ret == 0)
|
||||
client->v6_route_add_cnt++;
|
||||
else if (ret < 0)
|
||||
else if (ret == 1)
|
||||
client->v6_route_upd8_cnt++;
|
||||
break;
|
||||
}
|
||||
|
@ -3453,6 +3453,10 @@ void rib_lookup_and_pushup(struct prefix_ipv4 *p, vrf_id_t vrf_id)
|
||||
* allocate: if they allocate a nexthop_group or backup nexthop info, they
|
||||
* must free those objects. If this returns < 0, an error has occurred and the
|
||||
* route_entry 're' has not been captured; the caller should free that also.
|
||||
*
|
||||
* -1 -> error
|
||||
* 0 -> Add
|
||||
* 1 -> update
|
||||
*/
|
||||
int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p,
|
||||
struct prefix_ipv6 *src_p, struct route_entry *re,
|
||||
@ -3567,11 +3571,12 @@ int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p,
|
||||
|
||||
SET_FLAG(re->status, ROUTE_ENTRY_CHANGED);
|
||||
rib_addnode(rn, re, 1);
|
||||
ret = 1;
|
||||
|
||||
/* Free implicit route.*/
|
||||
if (same)
|
||||
if (same) {
|
||||
ret = 1;
|
||||
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.
|
||||
|
Loading…
Reference in New Issue
Block a user