Promotion of data.lnx.2.0.c2-00002.

CRs      Change ID                                   Subject
--------------------------------------------------------------------------------------------------------------
1066542   I8b8e3d7cbfd4adfec82edbeca9ca082480211e12   IPACM: add support for new QMI message
1074690   I6cf50b45e6eeda8836be6beb6ade59579b91dd72   IPACM: fix compilation error on IPAv2
1068029   I770c78fbd693b1e537568da92ab32e6f98005137   IPACM: delete client header when interface goes down

Change-Id: I5e0c192acd3048fb67339aed2fa021626fddc8fc
CRs-Fixed: 1074690, 1068029, 1066542
diff --git a/ipacm/inc/IPACM_Defs.h b/ipacm/inc/IPACM_Defs.h
index b613392..d2cc362 100644
--- a/ipacm/inc/IPACM_Defs.h
+++ b/ipacm/inc/IPACM_Defs.h
@@ -95,7 +95,13 @@
 #define WWAN_QMI_IOCTL_DEVICE_NAME "/dev/wwan_ioctl"
 #define IPA_DEVICE_NAME "/dev/ipa"
 #define MAX_NUM_PROP 2
+
+#ifndef FEATURE_IPA_V3
 #define IPA_MAX_FLT_RULE 50
+#else
+#define IPA_MAX_FLT_RULE 100
+#endif
+
 #define TCP_FIN_SHIFT 16
 #define TCP_SYN_SHIFT 17
 #define TCP_RST_SHIFT 18
diff --git a/ipacm/src/IPACM_Filtering.cpp b/ipacm/src/IPACM_Filtering.cpp
index 7faecad..22eb19c 100644
--- a/ipacm/src/IPACM_Filtering.cpp
+++ b/ipacm/src/IPACM_Filtering.cpp
@@ -260,6 +260,9 @@
 {
 	int ret = 0, cnt, num_rules = 0, pos = 0;
 	ipa_install_fltr_rule_req_msg_v01 qmi_rule_msg;
+#ifdef FEATURE_IPA_V3
+	ipa_install_fltr_rule_req_ex_msg_v01 qmi_rule_ex_msg;
+#endif
 
 	int fd_wwan_ioctl = open(WWAN_QMI_IOCTL_DEVICE_NAME, O_RDWR);
 	if(fd_wwan_ioctl < 0)
@@ -279,6 +282,8 @@
 		IPACMDBG_H("Get %d WAN DL IPv6 filtering rules.\n", rule_table_v6->num_rules);
 	}
 
+	/* if it is not IPA v3, use old QMI format */
+#ifndef FEATURE_IPA_V3
 	if(num_rules > QMI_IPA_MAX_FILTERS_V01)
 	{
 		IPACMERR("The number of filtering rules exceed limit.\n");
@@ -291,27 +296,14 @@
 
 		if (num_rules > 0)
 		{
-#ifndef FEATURE_IPA_V3
 			qmi_rule_msg.filter_spec_list_valid = true;
-#else /* defined (FEATURE_IPA_V3) */
-			qmi_rule_msg.filter_spec_ex_list_valid = true;
-#endif
 		}
 		else
 		{
-#ifndef FEATURE_IPA_V3
 			qmi_rule_msg.filter_spec_list_valid = false;
-#else /* defined (FEATURE_IPA_V3) */
-			qmi_rule_msg.filter_spec_ex_list_valid = false;
-#endif
 		}
 
-#ifndef FEATURE_IPA_V3
 		qmi_rule_msg.filter_spec_list_len = num_rules;
-#else /* defined (FEATURE_IPA_V3) */
-		qmi_rule_msg.filter_spec_ex_list_len = num_rules;
-#endif
-
 		qmi_rule_msg.source_pipe_index_valid = 0;
 
 		IPACMDBG_H("Get %d WAN DL filtering rules in total.\n", num_rules);
@@ -322,7 +314,6 @@
 			{
 				if (pos < QMI_IPA_MAX_FILTERS_V01)
 				{
-#ifndef FEATURE_IPA_V3
 					qmi_rule_msg.filter_spec_list[pos].filter_spec_identifier = pos;
 					qmi_rule_msg.filter_spec_list[pos].ip_type = QMI_IPA_IP_TYPE_V4_V01;
 					qmi_rule_msg.filter_spec_list[pos].filter_action = GetQmiFilterAction(rule_table_v4->rules[cnt].rule.action);
@@ -333,19 +324,6 @@
 					memcpy(&qmi_rule_msg.filter_spec_list[pos].filter_rule,
 						&rule_table_v4->rules[cnt].rule.eq_attrib,
 						sizeof(struct ipa_filter_rule_type_v01));
-#else /* defined (FEATURE_IPA_V3) */
-					qmi_rule_msg.filter_spec_ex_list[pos].ip_type = QMI_IPA_IP_TYPE_V4_V01;
-					qmi_rule_msg.filter_spec_ex_list[pos].filter_action = GetQmiFilterAction(rule_table_v4->rules[cnt].rule.action);
-					qmi_rule_msg.filter_spec_ex_list[pos].is_routing_table_index_valid = 1;
-					qmi_rule_msg.filter_spec_ex_list[pos].route_table_index = rule_table_v4->rules[cnt].rule.rt_tbl_idx;
-					qmi_rule_msg.filter_spec_ex_list[pos].is_mux_id_valid = 1;
-					qmi_rule_msg.filter_spec_ex_list[pos].mux_id = mux_id;
-					qmi_rule_msg.filter_spec_ex_list[pos].rule_id = rule_table_v4->rules[cnt].rule.rule_id;
-					qmi_rule_msg.filter_spec_ex_list[pos].is_rule_hashable = rule_table_v4->rules[cnt].rule.hashable;
-					memcpy(&qmi_rule_msg.filter_spec_ex_list[pos].filter_rule,
-						&rule_table_v4->rules[cnt].rule.eq_attrib,
-						sizeof(struct ipa_filter_rule_type_v01));
-#endif
 					pos++;
 				}
 				else
@@ -361,7 +339,6 @@
 			{
 				if (pos < QMI_IPA_MAX_FILTERS_V01)
 				{
-#ifndef FEATURE_IPA_V3
 					qmi_rule_msg.filter_spec_list[pos].filter_spec_identifier = pos;
 					qmi_rule_msg.filter_spec_list[pos].ip_type = QMI_IPA_IP_TYPE_V6_V01;
 					qmi_rule_msg.filter_spec_list[pos].filter_action = GetQmiFilterAction(rule_table_v6->rules[cnt].rule.action);
@@ -372,19 +349,6 @@
 					memcpy(&qmi_rule_msg.filter_spec_list[pos].filter_rule,
 						&rule_table_v6->rules[cnt].rule.eq_attrib,
 						sizeof(struct ipa_filter_rule_type_v01));
-#else /* defined (FEATURE_IPA_V3) */
-					qmi_rule_msg.filter_spec_ex_list[pos].ip_type = QMI_IPA_IP_TYPE_V6_V01;
-					qmi_rule_msg.filter_spec_ex_list[pos].filter_action = GetQmiFilterAction(rule_table_v6->rules[cnt].rule.action);
-					qmi_rule_msg.filter_spec_ex_list[pos].is_routing_table_index_valid = 1;
-					qmi_rule_msg.filter_spec_ex_list[pos].route_table_index = rule_table_v6->rules[cnt].rule.rt_tbl_idx;
-					qmi_rule_msg.filter_spec_ex_list[pos].is_mux_id_valid = 1;
-					qmi_rule_msg.filter_spec_ex_list[pos].mux_id = mux_id;
-					qmi_rule_msg.filter_spec_ex_list[pos].rule_id = rule_table_v6->rules[cnt].rule.rule_id;
-					qmi_rule_msg.filter_spec_ex_list[pos].is_rule_hashable = rule_table_v6->rules[cnt].rule.hashable;
-					memcpy(&qmi_rule_msg.filter_spec_ex_list[pos].filter_rule,
-						&rule_table_v6->rules[cnt].rule.eq_attrib,
-						sizeof(struct ipa_filter_rule_type_v01));
-#endif
 					pos++;
 				}
 				else
@@ -402,7 +366,95 @@
 			return false;
 		}
 	}
-	IPACMDBG("Added Filtering rule %p\n", &qmi_rule_msg);
+	/* if it is IPA v3, use new QMI format */
+#else
+	if(num_rules > QMI_IPA_MAX_FILTERS_EX_V01)
+	{
+		IPACMERR("The number of filtering rules exceed limit.\n");
+		close(fd_wwan_ioctl);
+		return false;
+	}
+	else
+	{
+		memset(&qmi_rule_ex_msg, 0, sizeof(qmi_rule_ex_msg));
+
+		if (num_rules > 0)
+		{
+			qmi_rule_ex_msg.filter_spec_ex_list_valid = true;
+		}
+		else
+		{
+			qmi_rule_ex_msg.filter_spec_ex_list_valid = false;
+		}
+		qmi_rule_ex_msg.filter_spec_ex_list_len = num_rules;
+		qmi_rule_ex_msg.source_pipe_index_valid = 0;
+
+		IPACMDBG_H("Get %d WAN DL filtering rules in total.\n", num_rules);
+
+		if(rule_table_v4 != NULL)
+		{
+			for(cnt = rule_table_v4->num_rules - 1; cnt >= 0; cnt--)
+			{
+				if (pos < QMI_IPA_MAX_FILTERS_EX_V01)
+				{
+					qmi_rule_ex_msg.filter_spec_ex_list[pos].ip_type = QMI_IPA_IP_TYPE_V4_V01;
+					qmi_rule_ex_msg.filter_spec_ex_list[pos].filter_action = GetQmiFilterAction(rule_table_v4->rules[cnt].rule.action);
+					qmi_rule_ex_msg.filter_spec_ex_list[pos].is_routing_table_index_valid = 1;
+					qmi_rule_ex_msg.filter_spec_ex_list[pos].route_table_index = rule_table_v4->rules[cnt].rule.rt_tbl_idx;
+					qmi_rule_ex_msg.filter_spec_ex_list[pos].is_mux_id_valid = 1;
+					qmi_rule_ex_msg.filter_spec_ex_list[pos].mux_id = mux_id;
+					qmi_rule_ex_msg.filter_spec_ex_list[pos].rule_id = rule_table_v4->rules[cnt].rule.rule_id;
+					qmi_rule_ex_msg.filter_spec_ex_list[pos].is_rule_hashable = rule_table_v4->rules[cnt].rule.hashable;
+					memcpy(&qmi_rule_ex_msg.filter_spec_ex_list[pos].filter_rule,
+						&rule_table_v4->rules[cnt].rule.eq_attrib,
+						sizeof(struct ipa_filter_rule_type_v01));
+
+					pos++;
+				}
+				else
+				{
+					IPACMERR(" QMI only support max %d rules, current (%d)\n ",QMI_IPA_MAX_FILTERS_EX_V01, pos);
+				}
+			}
+		}
+
+		if(rule_table_v6 != NULL)
+		{
+			for(cnt = rule_table_v6->num_rules - 1; cnt >= 0; cnt--)
+			{
+				if (pos < QMI_IPA_MAX_FILTERS_EX_V01)
+				{
+					qmi_rule_ex_msg.filter_spec_ex_list[pos].ip_type = QMI_IPA_IP_TYPE_V6_V01;
+					qmi_rule_ex_msg.filter_spec_ex_list[pos].filter_action = GetQmiFilterAction(rule_table_v6->rules[cnt].rule.action);
+					qmi_rule_ex_msg.filter_spec_ex_list[pos].is_routing_table_index_valid = 1;
+					qmi_rule_ex_msg.filter_spec_ex_list[pos].route_table_index = rule_table_v6->rules[cnt].rule.rt_tbl_idx;
+					qmi_rule_ex_msg.filter_spec_ex_list[pos].is_mux_id_valid = 1;
+					qmi_rule_ex_msg.filter_spec_ex_list[pos].mux_id = mux_id;
+					qmi_rule_ex_msg.filter_spec_ex_list[pos].rule_id = rule_table_v6->rules[cnt].rule.rule_id;
+					qmi_rule_ex_msg.filter_spec_ex_list[pos].is_rule_hashable = rule_table_v6->rules[cnt].rule.hashable;
+					memcpy(&qmi_rule_ex_msg.filter_spec_ex_list[pos].filter_rule,
+						&rule_table_v6->rules[cnt].rule.eq_attrib,
+						sizeof(struct ipa_filter_rule_type_v01));
+
+					pos++;
+				}
+				else
+				{
+					IPACMERR(" QMI only support max %d rules, current (%d)\n ",QMI_IPA_MAX_FILTERS_EX_V01, pos);
+				}
+			}
+		}
+
+		ret = ioctl(fd_wwan_ioctl, WAN_IOC_ADD_FLT_RULE_EX, &qmi_rule_ex_msg);
+		if (ret != 0)
+		{
+			IPACMERR("Failed adding Filtering rule %p with ret %d\n ", &qmi_rule_ex_msg, ret);
+			close(fd_wwan_ioctl);
+			return false;
+		}
+	}
+#endif
+
 	close(fd_wwan_ioctl);
 	return true;
 }
diff --git a/ipacm/src/IPACM_Lan.cpp b/ipacm/src/IPACM_Lan.cpp
index 251814a..a119746 100644
--- a/ipacm/src/IPACM_Lan.cpp
+++ b/ipacm/src/IPACM_Lan.cpp
@@ -2602,54 +2602,6 @@
 	}
 
 	IPACMDBG_H("Finished delete default iface ipv6 rules \n ");
-	/* clean eth-client header, routing rules */
-	IPACMDBG_H("left %d eth clients need to be deleted \n ", num_eth_client);
-	for (i = 0; i < num_eth_client; i++)
-	{
-			/* First reset nat rules and then route rules */
-			if(get_client_memptr(eth_client, i)->ipv4_set == true)
-			{
-				IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(eth_client, i)->v4_addr);
-				CtList->HandleNeighIpAddrDelEvt(get_client_memptr(eth_client, i)->v4_addr);
-			}
-
-			if (delete_eth_rtrules(i, IPA_IP_v4))
-			{
-				IPACMERR("unbale to delete ecm-client v4 route rules for index %d\n", i);
-				res = IPACM_FAILURE;
-				goto fail;
-			}
-
-			if (delete_eth_rtrules(i, IPA_IP_v6))
-			{
-				IPACMERR("unbale to delete ecm-client v6 route rules for index %d\n", i);
-				res = IPACM_FAILURE;
-				goto fail;
-			}
-
-			IPACMDBG_H("Delete %d client header\n", num_eth_client);
-
-
-			if(get_client_memptr(eth_client, i)->ipv4_header_set == true)
-			{
-				if (m_header.DeleteHeaderHdl(get_client_memptr(eth_client, i)->hdr_hdl_v4)
-					== false)
-				{
-					res = IPACM_FAILURE;
-					goto fail;
-				}
-			}
-
-			if(get_client_memptr(eth_client, i)->ipv6_header_set == true)
-			{
-			if (m_header.DeleteHeaderHdl(get_client_memptr(eth_client, i)->hdr_hdl_v6)
-					== false)
-			{
-				res = IPACM_FAILURE;
-				goto fail;
-			}
-			}
-	} /* end of for loop */
 
 	/* free the edm clients cache */
 	IPACMDBG_H("Free ecm clients cache\n");
@@ -2661,11 +2613,6 @@
 		IPACMDBG_H("depend Got pipe %d rm index : %d \n", tx_prop->tx[0].dst_pipe, IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]);
 		IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]);
 	}
-	/* check software routing fl rule hdl */
-	if (softwarerouting_act == true && rx_prop != NULL)
-	{
-		handle_software_routing_disable();
-	}
 
 	eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_DOWN, IPA_IP_MAX, NULL);
 
@@ -2688,6 +2635,56 @@
 	}
 #endif /* defined(FEATURE_IPA_ANDROID)*/
 fail:
+	/* clean eth-client header, routing rules */
+	IPACMDBG_H("left %d eth clients need to be deleted \n ", num_eth_client);
+	for (i = 0; i < num_eth_client; i++)
+	{
+		/* First reset nat rules and then route rules */
+		if(get_client_memptr(eth_client, i)->ipv4_set == true)
+		{
+			IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(eth_client, i)->v4_addr);
+			CtList->HandleNeighIpAddrDelEvt(get_client_memptr(eth_client, i)->v4_addr);
+		}
+
+		if (delete_eth_rtrules(i, IPA_IP_v4))
+		{
+			IPACMERR("unbale to delete ecm-client v4 route rules for index %d\n", i);
+			res = IPACM_FAILURE;
+		}
+
+		if (delete_eth_rtrules(i, IPA_IP_v6))
+		{
+			IPACMERR("unbale to delete ecm-client v6 route rules for index %d\n", i);
+			res = IPACM_FAILURE;
+		}
+
+		IPACMDBG_H("Delete %d client header\n", num_eth_client);
+
+		if(get_client_memptr(eth_client, i)->ipv4_header_set == true)
+		{
+			if (m_header.DeleteHeaderHdl(get_client_memptr(eth_client, i)->hdr_hdl_v4)
+				== false)
+			{
+				res = IPACM_FAILURE;
+			}
+		}
+
+		if(get_client_memptr(eth_client, i)->ipv6_header_set == true)
+		{
+			if (m_header.DeleteHeaderHdl(get_client_memptr(eth_client, i)->hdr_hdl_v6)
+					== false)
+			{
+				res = IPACM_FAILURE;
+			}
+		}
+	} /* end of for loop */
+
+	/* check software routing fl rule hdl */
+	if (softwarerouting_act == true && rx_prop != NULL)
+	{
+		handle_software_routing_disable();
+	}
+
 	if (odu_route_rule_v4_hdl != NULL)
 	{
 		free(odu_route_rule_v4_hdl);
diff --git a/ipacm/src/IPACM_Wlan.cpp b/ipacm/src/IPACM_Wlan.cpp
index 00754a1..c067550 100644
--- a/ipacm/src/IPACM_Wlan.cpp
+++ b/ipacm/src/IPACM_Wlan.cpp
@@ -1653,67 +1653,8 @@
 	}
 	IPACMDBG_H("finished deleting default RT rules\n ");
 
-	/* check software routing fl rule hdl */
-	if (softwarerouting_act == true && rx_prop != NULL )
-	{
-		IPACMDBG_H("Delete sw routing filtering rules\n");
-		IPACM_Iface::handle_software_routing_disable();
-	}
-	IPACMDBG_H("finished delete software-routing filtering rules\n ");
-
-
-	/* clean wifi-client header, routing rules */
-	/* clean wifi client rule*/
-	IPACMDBG_H("left %d wifi clients need to be deleted \n ", num_wifi_client);
-
 	eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_DOWN, IPA_IP_MAX, NULL);
 
-	for (i = 0; i < num_wifi_client; i++)
-	{
-		/* First reset nat rules and then route rules */
-		if(get_client_memptr(wlan_client, i)->ipv4_set == true)
-		{
-	        IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(wlan_client, i)->v4_addr);
-			CtList->HandleNeighIpAddrDelEvt(get_client_memptr(wlan_client, i)->v4_addr);
-		}
-
-		if (delete_default_qos_rtrules(i, IPA_IP_v4))
-		{
-			IPACMERR("unbale to delete v4 default qos route rules for index: %d\n", i);
-			res = IPACM_FAILURE;
-			goto fail;
-		}
-
-		if (delete_default_qos_rtrules(i, IPA_IP_v6))
-		{
-			IPACMERR("unbale to delete v6 default qos route rules for index: %d\n", i);
-			res = IPACM_FAILURE;
-			goto fail;
-		}
-
-		IPACMDBG_H("Delete %d client header\n", num_wifi_client);
-
-		if(get_client_memptr(wlan_client, i)->ipv4_header_set == true)
-		{
-			if (m_header.DeleteHeaderHdl(get_client_memptr(wlan_client, i)->hdr_hdl_v4)
-				== false)
-			{
-				res = IPACM_FAILURE;
-				goto fail;
-			}
-		}
-
-		if(get_client_memptr(wlan_client, i)->ipv6_header_set == true)
-		{
-			if (m_header.DeleteHeaderHdl(get_client_memptr(wlan_client, i)->hdr_hdl_v6)
-					== false)
-			{
-				res = IPACM_FAILURE;
-				goto fail;
-			}
-		}
-	} /* end of for loop */
-
 	/* free the wlan clients cache */
 	IPACMDBG_H("Free wlan clients cache\n");
 
@@ -1733,6 +1674,59 @@
 #endif /* defined(FEATURE_IPA_ANDROID)*/
 
 fail:
+	/* clean wifi-client header, routing rules */
+	/* clean wifi client rule*/
+	IPACMDBG_H("left %d wifi clients need to be deleted \n ", num_wifi_client);
+	for (i = 0; i < num_wifi_client; i++)
+	{
+		/* First reset nat rules and then route rules */
+		if(get_client_memptr(wlan_client, i)->ipv4_set == true)
+		{
+	        IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(wlan_client, i)->v4_addr);
+			CtList->HandleNeighIpAddrDelEvt(get_client_memptr(wlan_client, i)->v4_addr);
+		}
+
+		if (delete_default_qos_rtrules(i, IPA_IP_v4))
+		{
+			IPACMERR("unbale to delete v4 default qos route rules for index: %d\n", i);
+			res = IPACM_FAILURE;
+		}
+
+		if (delete_default_qos_rtrules(i, IPA_IP_v6))
+		{
+			IPACMERR("unbale to delete v6 default qos route rules for index: %d\n", i);
+			res = IPACM_FAILURE;
+		}
+
+		IPACMDBG_H("Delete %d client header\n", num_wifi_client);
+
+		if(get_client_memptr(wlan_client, i)->ipv4_header_set == true)
+		{
+			if (m_header.DeleteHeaderHdl(get_client_memptr(wlan_client, i)->hdr_hdl_v4)
+				== false)
+			{
+				res = IPACM_FAILURE;
+			}
+		}
+
+		if(get_client_memptr(wlan_client, i)->ipv6_header_set == true)
+		{
+			if (m_header.DeleteHeaderHdl(get_client_memptr(wlan_client, i)->hdr_hdl_v6)
+					== false)
+			{
+				res = IPACM_FAILURE;
+			}
+		}
+	} /* end of for loop */
+
+	/* check software routing fl rule hdl */
+	if (softwarerouting_act == true && rx_prop != NULL )
+	{
+		IPACMDBG_H("Delete sw routing filtering rules\n");
+		IPACM_Iface::handle_software_routing_disable();
+	}
+	IPACMDBG_H("finished delete software-routing filtering rules\n ");
+
 	/* Delete corresponding ipa_rm_resource_name of RX-endpoint after delete all IPV4V6 FT-rule */
 	if (rx_prop != NULL)
 	{