From 4b41703a181b7187d9ff8cb744eb96d09997387c Mon Sep 17 00:00:00 2001 From: Suman Ghosh Date: Wed, 19 Feb 2020 15:09:19 +0530 Subject: [qca-nss-ecm] Fix for ref leak during multicast 'to' hierarchy creation Change-Id: I89df9dbe5ea054cf3b87d55ce68a751cb1d6c24f Signed-off-by: Suman Ghosh --- ecm_interface.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/ecm_interface.c b/ecm_interface.c index 4f7a886..2a0ca5b 100644 --- a/ecm_interface.c +++ b/ecm_interface.c @@ -3885,13 +3885,13 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_ dest_dev = dev_get_by_index(&init_net, *dst_if_index); if (!dest_dev) { if (!src_dev_is_bridge) { - int i; - /* * If already constructed any interface heirarchies before hitting * this error condition then Deref all interface heirarchies. */ if (valid_if > 0) { + int i; + for (i = 0; i < valid_if; i++) { ifaces = ecm_db_multicast_if_heirarchy_get(interfaces, i); ecm_db_multicast_copy_if_heirarchy(to_list_single, ifaces); @@ -3902,11 +3902,14 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_ /* * If valid netdev not found, Return 0 */ + if (br_dev_src) { + dev_put(br_dev_src); + } + return 0; } dest_dev = br_dev_src; - } dest_dev_type = dest_dev->type; @@ -3945,6 +3948,10 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_ } } + if (br_dev_src && (dest_dev != br_dev_src)) { + dev_put(br_dev_src); + } + dev_put(dest_dev); return 0; } @@ -3972,6 +3979,10 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_ ecm_db_connection_interfaces_deref(to_list_single, interface_first_base[i]); } + if (br_dev_src && (dest_dev != br_dev_src)) { + dev_put(br_dev_src); + } + dev_put(dest_dev); dev_put(mc_br_slave_dev); return 0; @@ -3997,6 +4008,10 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_ } } + if (br_dev_src && (dest_dev != br_dev_src)) { + dev_put(br_dev_src); + } + dev_put(dest_dev); dev_put(mc_br_slave_dev); return 0; @@ -4032,6 +4047,10 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_ } } + if (br_dev_src && (dest_dev != br_dev_src)) { + dev_put(br_dev_src); + } + dev_put(dest_dev); return 0; } @@ -4042,8 +4061,15 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_ valid_if++; } - dev_put(dest_dev); + if (dest_dev != br_dev_src) { + dev_put(dest_dev); + } } + + if (br_dev_src) { + dev_put(br_dev_src); + } + return total_ii_count; } EXPORT_SYMBOL(ecm_interface_multicast_heirarchy_construct_routed); -- cgit v1.1