summaryrefslogtreecommitdiffstats
path: root/staticd
diff options
context:
space:
mode:
authorIgor Ryzhov <iryzhov@nfware.com>2024-02-03 20:41:37 +0100
committerIgor Ryzhov <iryzhov@nfware.com>2024-02-04 21:28:10 +0100
commit3c05d53bf8defc36acdfe6e78064e068d60c649f (patch)
treec074aa6eaf19c7132618b6ea00a89cb14df70575 /staticd
parentstaticd: add a separate function for uninstalling nexthops (diff)
downloadfrr-3c05d53bf8defc36acdfe6e78064e068d60c649f.tar.xz
frr-3c05d53bf8defc36acdfe6e78064e068d60c649f.zip
staticd: fix nht memory leak
When a static route with a gateway nexthop is created, the nexthop is sent to zebra for NHT, and added to a local hash. When the nexthop's VRF is deleted from kernel, nexthop still stays in the hash. This is a memory leak, because it is never deleted from there. Even if the VRF is recreated in kernel, it is assigned with a new `vrf_id` so the old hash entry is not reused, and a new one is created. To fix the issue, remove all nexthops from the hash when the corresponding VRF is deleted, do not add nexthops to the hash if their corresponding VRF doesn't exist in kernel and don't add the same nexthop to the hash multiple times. Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
Diffstat (limited to 'staticd')
-rw-r--r--staticd/static_routes.c41
1 files changed, 6 insertions, 35 deletions
diff --git a/staticd/static_routes.c b/staticd/static_routes.c
index 6c83c82c0..cba38183b 100644
--- a/staticd/static_routes.c
+++ b/staticd/static_routes.c
@@ -87,11 +87,6 @@ void zebra_stable_node_cleanup(struct route_table *table,
/* Install static path into rib. */
void static_install_path(struct static_path *pn)
{
- struct static_nexthop *nh;
-
- frr_each(static_nexthop_list, &pn->nexthop_list, nh)
- static_zebra_nht_register(nh, true);
-
if (static_nexthop_list_count(&pn->nexthop_list))
static_zebra_route_add(pn, true);
}
@@ -492,7 +487,6 @@ static void static_fixup_vrf(struct vrf *vrf, struct route_table *stable,
continue;
nh->nh_vrf_id = vrf->vrf_id;
- nh->nh_registered = false;
if (nh->ifname[0]) {
ifp = if_lookup_by_name(nh->ifname,
nh->nh_vrf_id);
@@ -502,7 +496,7 @@ static void static_fixup_vrf(struct vrf *vrf, struct route_table *stable,
continue;
}
- static_install_path(pn);
+ static_install_nexthop(nh);
}
}
}
@@ -520,8 +514,6 @@ static void static_fixup_vrf(struct vrf *vrf, struct route_table *stable,
static void static_enable_vrf(struct route_table *stable, afi_t afi, safi_t safi)
{
struct route_node *rn;
- struct static_nexthop *nh;
- struct interface *ifp;
struct static_path *pn;
struct static_route_info *si;
@@ -529,22 +521,8 @@ static void static_enable_vrf(struct route_table *stable, afi_t afi, safi_t safi
si = static_route_info_from_rnode(rn);
if (!si)
continue;
- frr_each(static_path_list, &si->path_list, pn) {
- frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
- if (nh->nh_vrf_id == VRF_UNKNOWN)
- continue;
- if (nh->ifname[0]) {
- ifp = if_lookup_by_name(nh->ifname,
- nh->nh_vrf_id);
- if (ifp)
- nh->ifindex = ifp->ifindex;
- else
- continue;
- }
-
- static_install_path(pn);
- }
- }
+ frr_each(static_path_list, &si->path_list, pn)
+ static_install_path(pn);
}
}
@@ -606,7 +584,7 @@ static void static_cleanup_vrf(struct vrf *vrf, struct route_table *stable,
if (strcmp(vrf->name, nh->nh_vrfname) != 0)
continue;
- static_uninstall_path(pn);
+ static_uninstall_nexthop(nh);
nh->nh_vrf_id = VRF_UNKNOWN;
nh->ifindex = IFINDEX_INTERNAL;
@@ -627,7 +605,6 @@ static void static_disable_vrf(struct route_table *stable,
afi_t afi, safi_t safi)
{
struct route_node *rn;
- struct static_nexthop *nh;
struct static_path *pn;
struct static_route_info *si;
@@ -635,14 +612,8 @@ static void static_disable_vrf(struct route_table *stable,
si = static_route_info_from_rnode(rn);
if (!si)
continue;
- frr_each(static_path_list, &si->path_list, pn) {
- frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
- if (nh->nh_vrf_id == VRF_UNKNOWN)
- continue;
-
- static_uninstall_path(pn);
- }
- }
+ frr_each(static_path_list, &si->path_list, pn)
+ static_uninstall_path(pn);
}
}