diff options
| author | Donald Sharp <donaldsharp72@gmail.com> | 2025-04-11 19:54:03 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-04-11 19:54:03 -0400 |
| commit | bd8ee74b49424e0e137d13d62e989892004ce027 (patch) | |
| tree | 36f8261fcbcbabc7e8fd82cf88d2be76122f3eed | |
| parent | 85bb2155db804b34d3dee4d7dd17461f9435eb41 (diff) | |
| parent | 55ea74d6304a8d5dc68ac39b1198f150fe00aa9c (diff) | |
Merge pull request #18645 from louis-6wind/fix-zebra-pbr-leak
zebra: fix pbr_iptable memory leak
| -rw-r--r-- | zebra/zapi_msg.c | 3 | ||||
| -rw-r--r-- | zebra/zebra_pbr.c | 62 | ||||
| -rw-r--r-- | zebra/zebra_pbr.h | 5 |
3 files changed, 35 insertions, 35 deletions
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index d4e65eb18c..fc78f87eb1 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -3872,12 +3872,13 @@ static inline void zebra_neigh_ip_del(ZAPI_HANDLER_ARGS) static inline void zread_iptable(ZAPI_HANDLER_ARGS) { struct zebra_pbr_iptable *zpi = - XCALLOC(MTYPE_PBR_OBJ, sizeof(struct zebra_pbr_iptable)); + XCALLOC(MTYPE_PBR_IPTABLE, sizeof(struct zebra_pbr_iptable)); struct stream *s; s = msg; zpi->interface_name_list = list_new(); + zpi->interface_name_list->del = zebra_pbr_iptable_interface_name_list_free; zpi->sock = client->sock; zpi->vrf_id = zvrf->vrf->vrf_id; STREAM_GETL(s, zpi->unique); diff --git a/zebra/zebra_pbr.c b/zebra/zebra_pbr.c index 7f3635702f..49846a00c8 100644 --- a/zebra/zebra_pbr.c +++ b/zebra/zebra_pbr.c @@ -23,7 +23,11 @@ /* definitions */ DEFINE_MTYPE_STATIC(ZEBRA, PBR_IPTABLE_IFNAME, "PBR interface list"); -DEFINE_MTYPE(ZEBRA, PBR_OBJ, "PBR"); +DEFINE_MTYPE_STATIC(ZEBRA, PBR_RULE, "PBR rule"); +DEFINE_MTYPE_STATIC(ZEBRA, PBR_IPSET, "PBR ipset"); +DEFINE_MTYPE_STATIC(ZEBRA, PBR_IPSET_ENTRY, "PBR ipset entry"); +DEFINE_MTYPE(ZEBRA, PBR_IPTABLE, "PBR iptable"); + /* definitions */ static const struct message ipset_type_msg[] = { @@ -151,7 +155,7 @@ void zebra_pbr_rules_free(void *arg) rule = (struct zebra_pbr_rule *)arg; (void)dplane_pbr_rule_delete(rule); - XFREE(MTYPE_PBR_OBJ, rule); + XFREE(MTYPE_PBR_RULE, rule); } uint32_t zebra_pbr_rules_hash_key(const void *arg) @@ -274,7 +278,7 @@ void zebra_pbr_ipset_free(void *arg) ipset = (struct zebra_pbr_ipset *)arg; hook_call(zebra_pbr_ipset_update, 0, ipset); - XFREE(MTYPE_PBR_OBJ, ipset); + XFREE(MTYPE_PBR_IPSET, ipset); } uint32_t zebra_pbr_ipset_hash_key(const void *arg) @@ -318,7 +322,7 @@ void zebra_pbr_ipset_entry_free(void *arg) hook_call(zebra_pbr_ipset_entry_update, 0, ipset); - XFREE(MTYPE_PBR_OBJ, ipset); + XFREE(MTYPE_PBR_IPSET_ENTRY, ipset); } uint32_t zebra_pbr_ipset_entry_hash_key(const void *arg) @@ -379,23 +383,16 @@ bool zebra_pbr_ipset_entry_hash_equal(const void *arg1, const void *arg2) static void _zebra_pbr_iptable_free_all(void *arg, bool all) { struct zebra_pbr_iptable *iptable; - struct listnode *node, *nnode; - char *name; iptable = (struct zebra_pbr_iptable *)arg; if (all) hook_call(zebra_pbr_iptable_update, 0, iptable); - if (iptable->interface_name_list) { - for (ALL_LIST_ELEMENTS(iptable->interface_name_list, node, - nnode, name)) { - XFREE(MTYPE_PBR_IPTABLE_IFNAME, name); - list_delete_node(iptable->interface_name_list, node); - } + if (iptable->interface_name_list) list_delete(&iptable->interface_name_list); - } - XFREE(MTYPE_PBR_OBJ, iptable); + + XFREE(MTYPE_PBR_IPTABLE, iptable); } void zebra_pbr_iptable_free(void *arg) @@ -477,7 +474,7 @@ static void *pbr_rule_alloc_intern(void *arg) zpr = (struct zebra_pbr_rule *)arg; - new = XCALLOC(MTYPE_PBR_OBJ, sizeof(*new)); + new = XCALLOC(MTYPE_PBR_RULE, sizeof(*new)); memcpy(new, zpr, sizeof(*zpr)); @@ -491,7 +488,7 @@ static struct zebra_pbr_rule *pbr_rule_free(struct zebra_pbr_rule *hash_data, zebra_neigh_deref(hash_data); hash_release(zrouter.rules_hash, hash_data); if (free_data) { - XFREE(MTYPE_PBR_OBJ, hash_data); + XFREE(MTYPE_PBR_RULE, hash_data); return NULL; } @@ -729,7 +726,7 @@ void zebra_pbr_add_rule(struct zebra_pbr_rule *rule) (void)dplane_pbr_rule_update(found, new); /* release the old hash data */ if (old) - XFREE(MTYPE_PBR_OBJ, old); + XFREE(MTYPE_PBR_RULE, old); } else { if (IS_ZEBRA_DEBUG_PBR) zlog_debug( @@ -897,7 +894,7 @@ static void *pbr_ipset_alloc_intern(void *arg) zpi = (struct zebra_pbr_ipset *)arg; - new = XCALLOC(MTYPE_PBR_OBJ, sizeof(struct zebra_pbr_ipset)); + new = XCALLOC(MTYPE_PBR_IPSET, sizeof(struct zebra_pbr_ipset)); memcpy(new, zpi, sizeof(*zpi)); @@ -918,7 +915,7 @@ void zebra_pbr_destroy_ipset(struct zebra_pbr_ipset *ipset) (void)dplane_pbr_ipset_delete(ipset); if (lookup) { hash_release(zrouter.ipset_hash, lookup); - XFREE(MTYPE_PBR_OBJ, lookup); + XFREE(MTYPE_PBR_IPSET, lookup); } else zlog_debug( "%s: IPSet Entry being deleted we know nothing about", @@ -971,7 +968,7 @@ static void *pbr_ipset_entry_alloc_intern(void *arg) zpi = (struct zebra_pbr_ipset_entry *)arg; - new = XCALLOC(MTYPE_PBR_OBJ, sizeof(struct zebra_pbr_ipset_entry)); + new = XCALLOC(MTYPE_PBR_IPSET_ENTRY, sizeof(struct zebra_pbr_ipset_entry)); memcpy(new, zpi, sizeof(*zpi)); @@ -993,12 +990,19 @@ void zebra_pbr_del_ipset_entry(struct zebra_pbr_ipset_entry *ipset) (void)dplane_pbr_ipset_entry_delete(ipset); if (lookup) { hash_release(zrouter.ipset_entry_hash, lookup); - XFREE(MTYPE_PBR_OBJ, lookup); + XFREE(MTYPE_PBR_IPSET_ENTRY, lookup); } else zlog_debug("%s: IPSet being deleted we know nothing about", __func__); } +void zebra_pbr_iptable_interface_name_list_free(void *arg) +{ + char *name = arg; + + XFREE(MTYPE_PBR_IPTABLE_IFNAME, name); +} + static void *pbr_iptable_alloc_intern(void *arg) { struct zebra_pbr_iptable *zpi; @@ -1008,11 +1012,12 @@ static void *pbr_iptable_alloc_intern(void *arg) zpi = (struct zebra_pbr_iptable *)arg; - new = XCALLOC(MTYPE_PBR_OBJ, sizeof(struct zebra_pbr_iptable)); + new = XCALLOC(MTYPE_PBR_IPTABLE, sizeof(struct zebra_pbr_iptable)); /* Deep structure copy */ memcpy(new, zpi, sizeof(*zpi)); new->interface_name_list = list_new(); + new->interface_name_list->del = zebra_pbr_iptable_interface_name_list_free; if (zpi->interface_name_list) { for (ALL_LIST_ELEMENTS_RO(zpi->interface_name_list, ln, ifname)) @@ -1039,18 +1044,9 @@ void zebra_pbr_del_iptable(struct zebra_pbr_iptable *iptable) lookup = hash_lookup(zrouter.iptable_hash, iptable); (void)dplane_pbr_iptable_delete(iptable); if (lookup) { - struct listnode *node, *nnode; - char *name; - hash_release(zrouter.iptable_hash, lookup); - for (ALL_LIST_ELEMENTS(iptable->interface_name_list, - node, nnode, name)) { - XFREE(MTYPE_PBR_IPTABLE_IFNAME, name); - list_delete_node(iptable->interface_name_list, - node); - } - list_delete(&iptable->interface_name_list); - XFREE(MTYPE_PBR_OBJ, lookup); + list_delete(&lookup->interface_name_list); + XFREE(MTYPE_PBR_IPTABLE, lookup); } else zlog_debug("%s: IPTable being deleted we know nothing about", __func__); diff --git a/zebra/zebra_pbr.h b/zebra/zebra_pbr.h index 1e4b5cd0f3..25868a6c1e 100644 --- a/zebra/zebra_pbr.h +++ b/zebra/zebra_pbr.h @@ -21,7 +21,8 @@ extern "C" { #endif /* Memory type for PBR objects. */ -DECLARE_MTYPE(PBR_OBJ); +DECLARE_MTYPE(PBR_IPTABLE); + struct zebra_pbr_action { afi_t afi; @@ -195,6 +196,8 @@ struct zebra_pbr_ipset *zebra_pbr_lookup_ipset_pername(char *ipsetname); void zebra_pbr_add_ipset_entry(struct zebra_pbr_ipset_entry *ipset); void zebra_pbr_del_ipset_entry(struct zebra_pbr_ipset_entry *ipset); +void zebra_pbr_iptable_interface_name_list_free(void *arg); + void zebra_pbr_add_iptable(struct zebra_pbr_iptable *iptable); void zebra_pbr_del_iptable(struct zebra_pbr_iptable *iptable); void zebra_pbr_process_iptable(struct zebra_dplane_ctx *ctx); |
