zebra: fix iptable memleak, fix free funcs

- Fix iptable freeing code to free malloc'd list
- malloc iptable in zapi handler and use those functions to free it when
  done to fix a linked list memleak

Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
This commit is contained in:
Quentin Young 2020-01-03 22:28:53 -05:00
parent b833cc1ff4
commit 8b5c4dce07
2 changed files with 33 additions and 28 deletions

View File

@ -2459,37 +2459,39 @@ stream_failure:
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_TMP, sizeof(struct zebra_pbr_iptable));
struct stream *s; struct stream *s;
s = msg; s = msg;
memset(&zpi, 0, sizeof(zpi)); zpi->interface_name_list = list_new();
zpi->sock = client->sock;
zpi.interface_name_list = list_new(); zpi->vrf_id = zvrf->vrf->vrf_id;
zpi.sock = client->sock; STREAM_GETL(s, zpi->unique);
zpi.vrf_id = zvrf->vrf->vrf_id; STREAM_GETL(s, zpi->type);
STREAM_GETL(s, zpi.unique); STREAM_GETL(s, zpi->filter_bm);
STREAM_GETL(s, zpi.type); STREAM_GETL(s, zpi->action);
STREAM_GETL(s, zpi.filter_bm); STREAM_GETL(s, zpi->fwmark);
STREAM_GETL(s, zpi.action); STREAM_GET(&zpi->ipset_name, s, ZEBRA_IPSET_NAME_SIZE);
STREAM_GETL(s, zpi.fwmark); STREAM_GETW(s, zpi->pkt_len_min);
STREAM_GET(&zpi.ipset_name, s, ZEBRA_IPSET_NAME_SIZE); STREAM_GETW(s, zpi->pkt_len_max);
STREAM_GETW(s, zpi.pkt_len_min); STREAM_GETW(s, zpi->tcp_flags);
STREAM_GETW(s, zpi.pkt_len_max); STREAM_GETW(s, zpi->tcp_mask_flags);
STREAM_GETW(s, zpi.tcp_flags); STREAM_GETC(s, zpi->dscp_value);
STREAM_GETW(s, zpi.tcp_mask_flags); STREAM_GETC(s, zpi->fragment);
STREAM_GETC(s, zpi.dscp_value); STREAM_GETC(s, zpi->protocol);
STREAM_GETC(s, zpi.fragment); STREAM_GETL(s, zpi->nb_interface);
STREAM_GETC(s, zpi.protocol); zebra_pbr_iptable_update_interfacelist(s, zpi);
STREAM_GETL(s, zpi.nb_interface);
zebra_pbr_iptable_update_interfacelist(s, &zpi);
if (hdr->command == ZEBRA_IPTABLE_ADD) if (hdr->command == ZEBRA_IPTABLE_ADD)
zebra_pbr_add_iptable(&zpi); zebra_pbr_add_iptable(zpi);
else else
zebra_pbr_del_iptable(&zpi); zebra_pbr_del_iptable(zpi);
stream_failure: stream_failure:
zebra_pbr_iptable_free(zpi);
zpi = NULL;
return; return;
} }

View File

@ -345,11 +345,13 @@ void zebra_pbr_iptable_free(void *arg)
iptable = (struct zebra_pbr_iptable *)arg; iptable = (struct zebra_pbr_iptable *)arg;
hook_call(zebra_pbr_iptable_update, 0, iptable); hook_call(zebra_pbr_iptable_update, 0, iptable);
for (ALL_LIST_ELEMENTS(iptable->interface_name_list, if (iptable->interface_name_list) {
node, nnode, name)) { for (ALL_LIST_ELEMENTS(iptable->interface_name_list, node,
XFREE(MTYPE_PBR_IPTABLE_IFNAME, name); nnode, name)) {
list_delete_node(iptable->interface_name_list, XFREE(MTYPE_PBR_IPTABLE_IFNAME, name);
node); list_delete_node(iptable->interface_name_list, node);
}
list_delete(&iptable->interface_name_list);
} }
XFREE(MTYPE_TMP, iptable); XFREE(MTYPE_TMP, iptable);
} }
@ -688,6 +690,7 @@ void zebra_pbr_del_iptable(struct zebra_pbr_iptable *iptable)
list_delete_node(iptable->interface_name_list, list_delete_node(iptable->interface_name_list,
node); node);
} }
list_delete(&iptable->interface_name_list);
XFREE(MTYPE_TMP, lookup); XFREE(MTYPE_TMP, lookup);
} else } else
zlog_debug("%s: IPTable being deleted we know nothing about", zlog_debug("%s: IPTable being deleted we know nothing about",