forked from Mirror/frr
Merge pull request #18645 from louis-6wind/fix-zebra-pbr-leak
zebra: fix pbr_iptable memory leak
This commit is contained in:
commit
bd8ee74b49
|
@ -3872,12 +3872,13 @@ static inline void zebra_neigh_ip_del(ZAPI_HANDLER_ARGS)
|
||||||
static inline void zread_iptable(ZAPI_HANDLER_ARGS)
|
static inline void zread_iptable(ZAPI_HANDLER_ARGS)
|
||||||
{
|
{
|
||||||
struct zebra_pbr_iptable *zpi =
|
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;
|
struct stream *s;
|
||||||
|
|
||||||
s = msg;
|
s = msg;
|
||||||
|
|
||||||
zpi->interface_name_list = list_new();
|
zpi->interface_name_list = list_new();
|
||||||
|
zpi->interface_name_list->del = zebra_pbr_iptable_interface_name_list_free;
|
||||||
zpi->sock = client->sock;
|
zpi->sock = client->sock;
|
||||||
zpi->vrf_id = zvrf->vrf->vrf_id;
|
zpi->vrf_id = zvrf->vrf->vrf_id;
|
||||||
STREAM_GETL(s, zpi->unique);
|
STREAM_GETL(s, zpi->unique);
|
||||||
|
|
|
@ -23,7 +23,11 @@
|
||||||
|
|
||||||
/* definitions */
|
/* definitions */
|
||||||
DEFINE_MTYPE_STATIC(ZEBRA, PBR_IPTABLE_IFNAME, "PBR interface list");
|
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 */
|
/* definitions */
|
||||||
static const struct message ipset_type_msg[] = {
|
static const struct message ipset_type_msg[] = {
|
||||||
|
@ -151,7 +155,7 @@ void zebra_pbr_rules_free(void *arg)
|
||||||
rule = (struct zebra_pbr_rule *)arg;
|
rule = (struct zebra_pbr_rule *)arg;
|
||||||
|
|
||||||
(void)dplane_pbr_rule_delete(rule);
|
(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)
|
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;
|
ipset = (struct zebra_pbr_ipset *)arg;
|
||||||
hook_call(zebra_pbr_ipset_update, 0, ipset);
|
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)
|
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);
|
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)
|
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)
|
static void _zebra_pbr_iptable_free_all(void *arg, bool all)
|
||||||
{
|
{
|
||||||
struct zebra_pbr_iptable *iptable;
|
struct zebra_pbr_iptable *iptable;
|
||||||
struct listnode *node, *nnode;
|
|
||||||
char *name;
|
|
||||||
|
|
||||||
iptable = (struct zebra_pbr_iptable *)arg;
|
iptable = (struct zebra_pbr_iptable *)arg;
|
||||||
|
|
||||||
if (all)
|
if (all)
|
||||||
hook_call(zebra_pbr_iptable_update, 0, iptable);
|
hook_call(zebra_pbr_iptable_update, 0, iptable);
|
||||||
|
|
||||||
if (iptable->interface_name_list) {
|
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);
|
|
||||||
}
|
|
||||||
list_delete(&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)
|
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;
|
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));
|
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);
|
zebra_neigh_deref(hash_data);
|
||||||
hash_release(zrouter.rules_hash, hash_data);
|
hash_release(zrouter.rules_hash, hash_data);
|
||||||
if (free_data) {
|
if (free_data) {
|
||||||
XFREE(MTYPE_PBR_OBJ, hash_data);
|
XFREE(MTYPE_PBR_RULE, hash_data);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -729,7 +726,7 @@ void zebra_pbr_add_rule(struct zebra_pbr_rule *rule)
|
||||||
(void)dplane_pbr_rule_update(found, new);
|
(void)dplane_pbr_rule_update(found, new);
|
||||||
/* release the old hash data */
|
/* release the old hash data */
|
||||||
if (old)
|
if (old)
|
||||||
XFREE(MTYPE_PBR_OBJ, old);
|
XFREE(MTYPE_PBR_RULE, old);
|
||||||
} else {
|
} else {
|
||||||
if (IS_ZEBRA_DEBUG_PBR)
|
if (IS_ZEBRA_DEBUG_PBR)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
|
@ -897,7 +894,7 @@ static void *pbr_ipset_alloc_intern(void *arg)
|
||||||
|
|
||||||
zpi = (struct zebra_pbr_ipset *)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));
|
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);
|
(void)dplane_pbr_ipset_delete(ipset);
|
||||||
if (lookup) {
|
if (lookup) {
|
||||||
hash_release(zrouter.ipset_hash, lookup);
|
hash_release(zrouter.ipset_hash, lookup);
|
||||||
XFREE(MTYPE_PBR_OBJ, lookup);
|
XFREE(MTYPE_PBR_IPSET, lookup);
|
||||||
} else
|
} else
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s: IPSet Entry being deleted we know nothing about",
|
"%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;
|
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));
|
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);
|
(void)dplane_pbr_ipset_entry_delete(ipset);
|
||||||
if (lookup) {
|
if (lookup) {
|
||||||
hash_release(zrouter.ipset_entry_hash, lookup);
|
hash_release(zrouter.ipset_entry_hash, lookup);
|
||||||
XFREE(MTYPE_PBR_OBJ, lookup);
|
XFREE(MTYPE_PBR_IPSET_ENTRY, lookup);
|
||||||
} else
|
} else
|
||||||
zlog_debug("%s: IPSet being deleted we know nothing about",
|
zlog_debug("%s: IPSet being deleted we know nothing about",
|
||||||
__func__);
|
__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)
|
static void *pbr_iptable_alloc_intern(void *arg)
|
||||||
{
|
{
|
||||||
struct zebra_pbr_iptable *zpi;
|
struct zebra_pbr_iptable *zpi;
|
||||||
|
@ -1008,11 +1012,12 @@ static void *pbr_iptable_alloc_intern(void *arg)
|
||||||
|
|
||||||
zpi = (struct zebra_pbr_iptable *)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 */
|
/* Deep structure copy */
|
||||||
memcpy(new, zpi, sizeof(*zpi));
|
memcpy(new, zpi, sizeof(*zpi));
|
||||||
new->interface_name_list = list_new();
|
new->interface_name_list = list_new();
|
||||||
|
new->interface_name_list->del = zebra_pbr_iptable_interface_name_list_free;
|
||||||
|
|
||||||
if (zpi->interface_name_list) {
|
if (zpi->interface_name_list) {
|
||||||
for (ALL_LIST_ELEMENTS_RO(zpi->interface_name_list, ln, ifname))
|
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);
|
lookup = hash_lookup(zrouter.iptable_hash, iptable);
|
||||||
(void)dplane_pbr_iptable_delete(iptable);
|
(void)dplane_pbr_iptable_delete(iptable);
|
||||||
if (lookup) {
|
if (lookup) {
|
||||||
struct listnode *node, *nnode;
|
|
||||||
char *name;
|
|
||||||
|
|
||||||
hash_release(zrouter.iptable_hash, lookup);
|
hash_release(zrouter.iptable_hash, lookup);
|
||||||
for (ALL_LIST_ELEMENTS(iptable->interface_name_list,
|
list_delete(&lookup->interface_name_list);
|
||||||
node, nnode, name)) {
|
XFREE(MTYPE_PBR_IPTABLE, lookup);
|
||||||
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);
|
|
||||||
} else
|
} else
|
||||||
zlog_debug("%s: IPTable being deleted we know nothing about",
|
zlog_debug("%s: IPTable being deleted we know nothing about",
|
||||||
__func__);
|
__func__);
|
||||||
|
|
|
@ -21,7 +21,8 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Memory type for PBR objects. */
|
/* Memory type for PBR objects. */
|
||||||
DECLARE_MTYPE(PBR_OBJ);
|
DECLARE_MTYPE(PBR_IPTABLE);
|
||||||
|
|
||||||
|
|
||||||
struct zebra_pbr_action {
|
struct zebra_pbr_action {
|
||||||
afi_t afi;
|
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_add_ipset_entry(struct zebra_pbr_ipset_entry *ipset);
|
||||||
void zebra_pbr_del_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_add_iptable(struct zebra_pbr_iptable *iptable);
|
||||||
void zebra_pbr_del_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);
|
void zebra_pbr_process_iptable(struct zebra_dplane_ctx *ctx);
|
||||||
|
|
Loading…
Reference in a new issue