ipacm: keep track of flt rule handles that are in use

Initialize an array to keep track which filtering handles
are in use to prevent a wraparound issue where we have 2
rules with the same ID leading to a problem with rule deletion.

Change-Id: I940c043f486860a1a694ad3b3a183cae44d1057e
Signed-off-by: Michael Adisumarta <madisuma@codeaurora.org>
diff --git a/ipacm/inc/IPACM_Filtering.h b/ipacm/inc/IPACM_Filtering.h
index 428c21a..6667235 100644
--- a/ipacm/inc/IPACM_Filtering.h
+++ b/ipacm/inc/IPACM_Filtering.h
@@ -48,6 +48,7 @@
 #include <linux/rmnet_ipa_fd_ioctl.h>
 
 #define IPA_PCIE_MODEM_RULE_ID_START 69
+#define IPA_PCIE_MODEM_RULE_ID_MAX 1000
 
 class IPACM_Filtering
 {
@@ -80,6 +81,7 @@
 	int fd; /* File descriptor of the IPA device node /dev/ipa */
 	int total_num_offload_rules;
 	int pcie_modem_rule_id;
+	bool pcie_modem_rule_id_in_use[IPA_PCIE_MODEM_RULE_ID_MAX];
 };
 
 #endif //IPACM_FILTERING_H
diff --git a/ipacm/src/IPACM_Filtering.cpp b/ipacm/src/IPACM_Filtering.cpp
index 8aa25a6..b230c36 100644
--- a/ipacm/src/IPACM_Filtering.cpp
+++ b/ipacm/src/IPACM_Filtering.cpp
@@ -60,6 +60,7 @@
 	}
 	total_num_offload_rules = 0;
 	pcie_modem_rule_id = 0;
+	memset(pcie_modem_rule_id_in_use, 0, sizeof(pcie_modem_rule_id_in_use));
 }
 
 IPACM_Filtering::~IPACM_Filtering()
@@ -710,7 +711,7 @@
 bool IPACM_Filtering::AddOffloadFilteringRule(struct ipa_ioc_add_flt_rule *flt_rule_tbl, uint8_t mux_id, uint8_t default_path)
 {
 #ifdef WAN_IOCTL_ADD_OFFLOAD_CONNECTION
-	int ret = 0, cnt, pos = 0;
+	int ret = 0, cnt, pos = 0, i;
 	ipa_add_offload_connection_req_msg_v01 qmi_add_msg;
 	int fd_wwan_ioctl = open(WWAN_QMI_IOCTL_DEVICE_NAME, O_RDWR);
 	if(fd_wwan_ioctl < 0)
@@ -807,7 +808,23 @@
 						sizeof(struct ipa_filter_rule_type_v01));
 					IPACMDBG_H("mux-id %d, hashable %d\n", qmi_add_msg.filter_spec_ex2_list[pos].mux_id, qmi_add_msg.filter_spec_ex2_list[pos].is_rule_hashable);
 					pos++;
-					pcie_modem_rule_id = (pcie_modem_rule_id + 1)%100;
+					pcie_modem_rule_id_in_use[pcie_modem_rule_id] = true;
+					for(i = 0; i < IPA_PCIE_MODEM_RULE_ID_MAX; i++)
+					{
+						pcie_modem_rule_id = (pcie_modem_rule_id + 1)%IPA_PCIE_MODEM_RULE_ID_MAX;
+						if(!pcie_modem_rule_id_in_use[pcie_modem_rule_id])
+							break;
+					}
+
+					if(i == IPA_PCIE_MODEM_RULE_ID_MAX)
+					{
+						IPACMERR("all handles are in use, max = %d\n", i);
+						return false;
+					}
+					else
+					{
+						IPACMDBG("next free pcie_modem_rule_id: %d\n", pcie_modem_rule_id);
+					}
 				}
 				else
 				{
@@ -892,6 +909,12 @@
 					/* passing rule-id to wan-driver */
 					qmi_del_msg.filter_handle_list[pos].filter_spec_identifier = flt_rule_tbl->hdl[cnt].hdl;
 					pos++;
+
+					/* set in use to false for future rule additions (need to subtract offset and mod max index) */
+					pcie_modem_rule_id_in_use[(IPA_PCIE_MODEM_RULE_ID_MAX + flt_rule_tbl->hdl[cnt].hdl - IPA_PCIE_MODEM_RULE_ID_START)
+						% IPA_PCIE_MODEM_RULE_ID_MAX] = false;
+					IPACMDBG("freeing pcie_modem_rule_id: %d\n", (IPA_PCIE_MODEM_RULE_ID_MAX + flt_rule_tbl->hdl[cnt].hdl -IPA_PCIE_MODEM_RULE_ID_START)
+						% IPA_PCIE_MODEM_RULE_ID_MAX);
 				}
 				else
 				{