]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: Fix memory leak in SRv6 locator delete
authorCarmine Scarpitta <carmine.scarpitta@uniroma2.it>
Tue, 23 Aug 2022 22:13:25 +0000 (00:13 +0200)
committerCarmine Scarpitta <carmine.scarpitta@uniroma2.it>
Wed, 24 Aug 2022 12:22:04 +0000 (14:22 +0200)
Running `bgp_srv6l3vpn_to_bgp_vrf` and `bgp_srv6l3vpn_to_bgp_vrf2`
topotests with `--valgrind-memleaks` gives several memory leak errors.
This is due to the way SRv6 locators are removed/unset in bgpd: when
an SRv6 locator is deleted or unset, the memory allocated for the
locator prefix (`tovpn_sid_locator`) is not freed.

This patch adds a `for` loop that iterates over the list of BGP
instances. For each BGP instance using the SRv6 locator to be
removed/unset, we use `XFREE()` to properly free the memory allocated
for `tovpn_sid_locator` after the SRv6 locator is removed or unset.

The memory allocated for `tovpn_sid_locator` cannot be freed before
calling `vpn_leak_postchange_all()`. This is because
after deleting an SRv6 locator, we call `vpn_leak_postchange_all()`
to handle the SRv6 locator deletion and send a BGP Prefix SID withdraw
message. `tovpn_sid_locator` is required to properly build the BGP
Prefix SID withdraw message. After calling `vpn_leak_postchange_all()`
we can safely remove the `tovpn_sid_locator` and free the allocated
memory.

Signed-off-by: Carmine Scarpitta <carmine.scarpitta@uniroma2.it>
bgpd/bgp_vty.c
bgpd/bgp_zebra.c

index 6488c94075d4e36ba0951ea1f12294b920c94a8e..ab3a24770f8539a15c43a2266ac9cdb85e86f9a2 100644 (file)
@@ -338,6 +338,20 @@ static int bgp_srv6_locator_unset(struct bgp *bgp)
        /* update vpn bgp processes */
        vpn_leak_postchange_all();
 
+       /* refresh tovpn_sid_locator */
+       for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp_vrf)) {
+               if (bgp_vrf->inst_type != BGP_INSTANCE_TYPE_VRF)
+                       continue;
+
+               /* refresh vpnv4 tovpn_sid_locator */
+               XFREE(MTYPE_BGP_SRV6_SID,
+                     bgp_vrf->vpn_policy[AFI_IP].tovpn_sid_locator);
+
+               /* refresh vpnv6 tovpn_sid_locator */
+               XFREE(MTYPE_BGP_SRV6_SID,
+                     bgp_vrf->vpn_policy[AFI_IP6].tovpn_sid_locator);
+       }
+
        /* clear locator name */
        memset(bgp->srv6_locator_name, 0, sizeof(bgp->srv6_locator_name));
 
index 33e8895becac52edd2b4f07b73f34206f2852fad..077785b55ac073ee90d69155ae8f1028b51504ed 100644 (file)
@@ -3209,7 +3209,7 @@ static int bgp_zebra_process_srv6_locator_delete(ZAPI_CALLBACK_ARGS)
        struct srv6_locator_chunk *chunk;
        struct bgp_srv6_function *func;
        struct bgp *bgp_vrf;
-       struct in6_addr *tovpn_sid;
+       struct in6_addr *tovpn_sid, *tovpn_sid_locator;
        struct prefix_ipv6 tmp_prefi;
 
        if (zapi_srv6_locator_decode(zclient->ibuf, &loc) < 0)
@@ -3266,6 +3266,37 @@ static int bgp_zebra_process_srv6_locator_delete(ZAPI_CALLBACK_ARGS)
        }
 
        vpn_leak_postchange_all();
+
+       /* refresh tovpn_sid_locator */
+       for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp_vrf)) {
+               if (bgp_vrf->inst_type != BGP_INSTANCE_TYPE_VRF)
+                       continue;
+
+               /* refresh vpnv4 tovpn_sid_locator */
+               tovpn_sid_locator =
+                       bgp_vrf->vpn_policy[AFI_IP].tovpn_sid_locator;
+               if (tovpn_sid_locator) {
+                       tmp_prefi.family = AF_INET6;
+                       tmp_prefi.prefixlen = IPV6_MAX_BITLEN;
+                       tmp_prefi.prefix = *tovpn_sid_locator;
+                       if (prefix_match((struct prefix *)&loc.prefix,
+                                        (struct prefix *)&tmp_prefi))
+                               XFREE(MTYPE_BGP_SRV6_SID, tovpn_sid_locator);
+               }
+
+               /* refresh vpnv6 tovpn_sid_locator */
+               tovpn_sid_locator =
+                       bgp_vrf->vpn_policy[AFI_IP6].tovpn_sid_locator;
+               if (tovpn_sid_locator) {
+                       tmp_prefi.family = AF_INET6;
+                       tmp_prefi.prefixlen = IPV6_MAX_BITLEN;
+                       tmp_prefi.prefix = *tovpn_sid_locator;
+                       if (prefix_match((struct prefix *)&loc.prefix,
+                                        (struct prefix *)&tmp_prefi))
+                               XFREE(MTYPE_BGP_SRV6_SID, tovpn_sid_locator);
+               }
+       }
+
        return 0;
 }