Merge "Opt out	of clang till issues are fixed"
diff --git a/ipacm/inc/IPACM_Defs.h b/ipacm/inc/IPACM_Defs.h
index b424d97..559daca 100644
--- a/ipacm/inc/IPACM_Defs.h
+++ b/ipacm/inc/IPACM_Defs.h
@@ -190,6 +190,10 @@
 	IPA_WAN_XLAT_CONNECT_EVENT,               /* 53 ipacm_event_data_fid */
 	IPA_TETHERING_STATS_UPDATE_EVENT,         /* 54 ipacm_event_data_fid */
 	IPA_NETWORK_STATS_UPDATE_EVENT,           /* 55 ipacm_event_data_fid */
+	IPA_HANDLE_WAN_UP_TETHER,                 /* 56 ipacm_event_iface_up_tehter */
+	IPA_HANDLE_WAN_DOWN_TETHER,               /* 57 ipacm_event_iface_up_tehter */
+	IPA_HANDLE_WAN_UP_V6_TETHER,		  /* 58 ipacm_event_iface_up_tehter */
+	IPA_HANDLE_WAN_DOWN_V6_TETHER,		  /* 59 ipacm_event_iface_up_tehter */
 	IPACM_EVENT_MAX
 } ipa_cm_event_id;
 
@@ -292,6 +296,7 @@
 typedef struct _ipacm_event_data_iptype
 {
 	int if_index;
+	int if_index_tether;
 	enum ipa_ip_type iptype;
 } ipacm_event_data_iptype;
 
@@ -330,6 +335,13 @@
 	uint8_t xlat_mux_id;
 }ipacm_event_iface_up;
 
+typedef struct _ipacm_event_iface_up_tether
+{
+	uint32_t if_index_tether;
+	uint32_t ipv6_prefix[2];
+	bool is_sta;
+}ipacm_event_iface_up_tehter;
+
 typedef enum
 {
 	Q6_WAN = 0,
diff --git a/ipacm/inc/IPACM_Lan.h b/ipacm/inc/IPACM_Lan.h
index 94a1c6d..3579567 100644
--- a/ipacm/inc/IPACM_Lan.h
+++ b/ipacm/inc/IPACM_Lan.h
@@ -315,6 +315,9 @@
 	/* handle tethering stats */
 	int handle_tethering_stats_event(ipa_get_data_stats_resp_msg_v01 *data);
 
+	/* handle tethering client */
+	int handle_tethering_client(bool reset, ipacm_client_enum ipa_client);
+
 	lan2lan_flt_rule_hdl lan2lan_flt_rule_hdl_v4[MAX_OFFLOAD_PAIR];
 	lan2lan_flt_rule_hdl lan2lan_flt_rule_hdl_v6[MAX_OFFLOAD_PAIR];
 
diff --git a/ipacm/inc/IPACM_Log.h b/ipacm/inc/IPACM_Log.h
index 131aab8..8fce44e 100644
--- a/ipacm/inc/IPACM_Log.h
+++ b/ipacm/inc/IPACM_Log.h
@@ -67,16 +67,16 @@
 static char buffer_send[MAX_BUF_LEN];
 static char dmesg_cmd[MAX_BUF_LEN];
 
-#define PERROR(fmt)   memset(buffer_send, 0, MAX_BUF_LEN);\
-					  snprintf(buffer_send,MAX_BUF_LEN,"%s:%d %s()", __FILE__, __LINE__, __FUNCTION__);\
-					  ipacm_log_send (buffer_send); \
-                      perror(fmt);
-
 #define IPACMDBG_DMESG(fmt, ...) memset(buffer_send, 0, MAX_BUF_LEN);\
 							     snprintf(buffer_send,MAX_BUF_LEN,"%s:%d %s: " fmt, __FILE__,  __LINE__, __FUNCTION__, ##__VA_ARGS__);\
 								 memset(dmesg_cmd, 0, MAX_BUF_LEN);\
 								 snprintf(dmesg_cmd, MAX_BUF_LEN, "echo %s > /dev/kmsg", buffer_send);\
 								 system(dmesg_cmd);
+#ifdef DEBUG
+#define PERROR(fmt)   memset(buffer_send, 0, MAX_BUF_LEN);\
+					  snprintf(buffer_send,MAX_BUF_LEN,"%s:%d %s()", __FILE__, __LINE__, __FUNCTION__);\
+					  ipacm_log_send (buffer_send); \
+                      perror(fmt);
 #define IPACMERR(fmt, ...)	memset(buffer_send, 0, MAX_BUF_LEN);\
 							snprintf(buffer_send,MAX_BUF_LEN,"ERR: %s:%d %s() " fmt, __FILE__,  __LINE__, __FUNCTION__, ##__VA_ARGS__);\
 							ipacm_log_send (buffer_send);\
@@ -85,6 +85,11 @@
 							 snprintf(buffer_send,MAX_BUF_LEN,"%s:%d %s() " fmt, __FILE__,  __LINE__, __FUNCTION__, ##__VA_ARGS__);\
 							 ipacm_log_send (buffer_send);\
 							 printf("%s:%d %s() " fmt, __FILE__,  __LINE__, __FUNCTION__, ##__VA_ARGS__);
+#else
+#define PERROR(fmt)   perror(fmt)
+#define IPACMERR(fmt, ...)   printf("ERR: %s:%d %s() " fmt, __FILE__,  __LINE__, __FUNCTION__, ##__VA_ARGS__);
+#define IPACMDBG_H(fmt, ...) printf("%s:%d %s() " fmt, __FILE__,  __LINE__, __FUNCTION__, ##__VA_ARGS__);
+#endif
 #define IPACMDBG(fmt, ...)	printf("%s:%d %s() " fmt, __FILE__,  __LINE__, __FUNCTION__, ##__VA_ARGS__);
 #define IPACMLOG(fmt, ...)  printf(fmt, ##__VA_ARGS__);
 
diff --git a/ipacm/inc/IPACM_Wan.h b/ipacm/inc/IPACM_Wan.h
index 159cc46..65f788f 100644
--- a/ipacm/inc/IPACM_Wan.h
+++ b/ipacm/inc/IPACM_Wan.h
@@ -97,18 +97,43 @@
 	static uint8_t xlat_mux_id;
 	/* IPACM interface name */
 	static char wan_up_dev_name[IF_NAME_LEN];
-
 	IPACM_Wan(int, ipacm_wan_iface_type, uint8_t *);
 	virtual ~IPACM_Wan();
 
-	static bool isWanUP()
+	static bool isWanUP(int ipa_if_num_tether)
 	{
+#ifdef FEATURE_IPA_ANDROID
+		int i;
+		for (i=1; i < ipa_if_num_tether_v4_total;i++)
+		{
+			if (ipa_if_num_tether_v4[i] == ipa_if_num_tether)
+			{
+				return wan_up;
+				break;
+			}
+		}
+		return false;
+#else
 		return wan_up;
+#endif
 	}
 
-	static bool isWanUP_V6()
+	static bool isWanUP_V6(int ipa_if_num_tether)
 	{
+#ifdef FEATURE_IPA_ANDROID
+		int i;
+		for (i=1; i < ipa_if_num_tether_v6_total;i++)
+		{
+			if (ipa_if_num_tether_v6[i] == ipa_if_num_tether)
+			{
+				return wan_up_v6;
+				break;
+			}
+		}
+		return false;
+#else
 		return wan_up_v6;
+#endif
 	}
 
 	static bool getXlat_Mux_Id()
@@ -137,6 +162,13 @@
 	{
 		return backhaul_is_wan_bridge;
 	}
+#ifdef FEATURE_IPA_ANDROID
+	/* IPACM interface id */
+	static int ipa_if_num_tether_v4_total;
+	static int ipa_if_num_tether_v4[IPA_MAX_IFACE_ENTRIES];
+	static int ipa_if_num_tether_v6_total;
+	static int ipa_if_num_tether_v6[IPA_MAX_IFACE_ENTRIES];
+#endif
 
 private:
 
@@ -341,6 +373,12 @@
 
 	bool check_dft_firewall_rules_attr_mask(IPACM_firewall_conf_t *firewall_config);
 
+#ifdef FEATURE_IPA_ANDROID
+	/* wan posting supported tether_iface */
+	int post_wan_up_tether_evt(ipa_ip_type iptype, int ipa_if_num_tether);
+
+	int post_wan_down_tether_evt(ipa_ip_type iptype, int ipa_if_num_tether);
+#endif
 	int config_dft_firewall_rules(ipa_ip_type iptype);
 
 	/* configure the initial firewall filter rules */
diff --git a/ipacm/src/Android.mk b/ipacm/src/Android.mk
index b7abfd1..5042501 100644
--- a/ipacm/src/Android.mk
+++ b/ipacm/src/Android.mk
@@ -27,8 +27,9 @@
 
 LOCAL_CFLAGS := -v
 LOCAL_CFLAGS += -DFEATURE_IPA_ANDROID
+ifneq (,$(filter userdebug eng, $(TARGET_BUILD_VARIANT)))
 LOCAL_CFLAGS += -DDEBUG
-
+endif
 filetoadd = bionic/libc/kernel/arch-arm/asm/posix_types.h
 LOCAL_CFLAGS += $(shell if [ -a $(filetoadd) ] ; then echo -include $(filetoadd) ; fi ;)
 filetoadd = bionic/libc/kernel/arch-arm/asm/byteorder.h
@@ -90,4 +91,4 @@
 
 endif # $(TARGET_ARCH)
 endif
-endif
\ No newline at end of file
+endif
diff --git a/ipacm/src/IPACM_Config.cpp b/ipacm/src/IPACM_Config.cpp
index 24890ed..f7d764a 100644
--- a/ipacm/src/IPACM_Config.cpp
+++ b/ipacm/src/IPACM_Config.cpp
@@ -150,7 +150,7 @@
 	{
 		IPACMERR("Unable to allocate iface_table memory.\n");
 		ret = IPACM_FAILURE;
-		goto fail;;
+		goto fail;
 	}
 
 	for (i = 0; i < cfg->iface_config.num_iface_entries; i++)
diff --git a/ipacm/src/IPACM_IfaceManager.cpp b/ipacm/src/IPACM_IfaceManager.cpp
index 03233b5..3024ce6 100644
--- a/ipacm/src/IPACM_IfaceManager.cpp
+++ b/ipacm/src/IPACM_IfaceManager.cpp
@@ -214,10 +214,17 @@
 				IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT, lan);
 				IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, lan);
 				IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, lan);
+#ifdef FEATURE_IPA_ANDROID
+				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_TETHER, lan);
+				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6_TETHER, lan);
+				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_TETHER, lan);
+				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6_TETHER, lan);
+#else
 				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP, lan);
 				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6, lan);
 				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN, lan);
 				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6, lan);
+#endif
 				IPACM_EvtDispatcher::registr(IPA_CFG_CHANGE_EVENT, lan); 				// register for IPA_CFG_CHANGE event
 				IPACM_EvtDispatcher::registr(IPA_PRIVATE_SUBNET_CHANGE_EVENT, lan); 	// register for IPA_PRIVATE_SUBNET_CHANGE_EVENT event
 #ifdef FEATURE_ETH_BRIDGE_LE
@@ -326,10 +333,17 @@
 				IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, wl);
 				IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, wl);
 				IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, wl);
+#ifdef FEATURE_IPA_ANDROID
+				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_TETHER, wl);
+				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6_TETHER, wl);
+				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_TETHER, wl);
+				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6_TETHER, wl);
+#else
 				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP, wl);
 				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6, wl);
 				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN, wl);
 				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6, wl);
+#endif
 				IPACM_EvtDispatcher::registr(IPA_PRIVATE_SUBNET_CHANGE_EVENT, wl); 	// register for IPA_PRIVATE_SUBNET_CHANGE_EVENT event
 #ifdef FEATURE_ETH_BRIDGE_LE
 				IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_LAN_CLIENT_ADD_EVENT, wl);
@@ -371,6 +385,7 @@
 					IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, w);
 #ifdef FEATURE_IPA_ANDROID
 					IPACM_EvtDispatcher::registr(IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT, w);
+					IPACM_EvtDispatcher::registr(IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT, w);
 					if(is_sta_mode == Q6_WAN)
 					{
 						IPACM_EvtDispatcher::registr(IPA_NETWORK_STATS_UPDATE_EVENT, w);
diff --git a/ipacm/src/IPACM_Lan.cpp b/ipacm/src/IPACM_Lan.cpp
index a8aff0b..4067e9f 100644
--- a/ipacm/src/IPACM_Lan.cpp
+++ b/ipacm/src/IPACM_Lan.cpp
@@ -296,6 +296,13 @@
 	lan_client_rt_from_wlan_info_count_v4 = 0;
 	lan_client_rt_from_wlan_info_count_v6 = 0;
 
+#ifdef FEATURE_IPA_ANDROID
+	/* set the IPA-client pipe enum */
+	if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == LAN_IF)
+	{
+		handle_tethering_client(false, IPACM_CLIENT_USB);
+	}
+#endif
 	return;
 }
 
@@ -319,6 +326,7 @@
 	int ipa_interface_index;
 	ipacm_ext_prop* ext_prop;
 	ipacm_event_iface_up* data_wan;
+	ipacm_event_iface_up_tehter* data_wan_tether;
 
 	switch (event)
 	{
@@ -491,39 +499,39 @@
 						handle_private_subnet(data->iptype);
 #endif
 
-						if (IPACM_Wan::isWanUP())
+						if (IPACM_Wan::isWanUP(ipa_if_num))
 						{
 							if(data->iptype == IPA_IP_v4 || data->iptype == IPA_IP_MAX)
 							{
-							if(IPACM_Wan::backhaul_is_sta_mode == false)
-							{
+								if(IPACM_Wan::backhaul_is_sta_mode == false)
+								{
 									ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
 									handle_wan_up_ex(ext_prop, IPA_IP_v4,
 												IPACM_Wan::getXlat_Mux_Id());
 								}
-							else
-							{
-								handle_wan_up(IPA_IP_v4);
+								else
+								{
+									handle_wan_up(IPA_IP_v4);
+								}
 							}
 						}
-						}
 
-						if(IPACM_Wan::isWanUP_V6())
+						if(IPACM_Wan::isWanUP_V6(ipa_if_num))
 						{
 							if((data->iptype == IPA_IP_v6 || data->iptype == IPA_IP_MAX) && num_dft_rt_v6 == 1)
 							{
 								install_ipv6_prefix_flt_rule(IPACM_Wan::backhaul_ipv6_prefix);
-							if(IPACM_Wan::backhaul_is_sta_mode == false)
-							{
+								if(IPACM_Wan::backhaul_is_sta_mode == false)
+								{
 									ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
 									handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
 								}
-							else
-							{
-								handle_wan_up(IPA_IP_v6);
+								else
+								{
+									handle_wan_up(IPA_IP_v6);
+								}
 							}
 						}
-						}
 
 						/* Post event to NAT */
 						if (data->iptype == IPA_IP_v4)
@@ -568,7 +576,107 @@
 			}
 		}
 		break;
+#ifdef FEATURE_IPA_ANDROID
+	case IPA_HANDLE_WAN_UP_TETHER:
+		IPACMDBG_H("Received IPA_HANDLE_WAN_UP_TETHER event\n");
 
+		data_wan_tether = (ipacm_event_iface_up_tehter*)param;
+		if(data_wan_tether == NULL)
+		{
+			IPACMERR("No event data is found.\n");
+			return;
+		}
+		IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d\n", data_wan_tether->is_sta,
+					data_wan_tether->if_index_tether);
+		if (iface_ipa_index_query(data_wan_tether->if_index_tether) == ipa_if_num)
+		{
+			if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
+			{
+				if(data_wan_tether->is_sta == false)
+				{
+					ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
+					handle_wan_up_ex(ext_prop, IPA_IP_v4, 0);
+				}
+				else
+				{
+					handle_wan_up(IPA_IP_v4);
+				}
+			}
+		}
+		break;
+
+	case IPA_HANDLE_WAN_UP_V6_TETHER:
+		IPACMDBG_H("Received IPA_HANDLE_WAN_UP_V6_TETHER event\n");
+
+		data_wan_tether = (ipacm_event_iface_up_tehter*)param;
+		if(data_wan_tether == NULL)
+		{
+			IPACMERR("No event data is found.\n");
+			return;
+		}
+		IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d\n", data_wan_tether->is_sta,
+					data_wan_tether->if_index_tether);
+		if (iface_ipa_index_query(data_wan_tether->if_index_tether) == ipa_if_num)
+		{
+			if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
+			{
+					install_ipv6_prefix_flt_rule(data_wan_tether->ipv6_prefix);
+					if(data_wan_tether->is_sta == false)
+					{
+						ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
+						handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
+					}
+					else
+					{
+						handle_wan_up(IPA_IP_v6);
+					}
+			}
+		}
+		break;
+
+	case IPA_HANDLE_WAN_DOWN_TETHER:
+		IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_TETHER event\n");
+		data_wan_tether = (ipacm_event_iface_up_tehter*)param;
+		if(data_wan_tether == NULL)
+		{
+			IPACMERR("No event data is found.\n");
+			return;
+		}
+		IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d\n", data_wan_tether->is_sta,
+					data_wan_tether->if_index_tether);
+		if (iface_ipa_index_query(data_wan_tether->if_index_tether) == ipa_if_num)
+		{
+			if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
+			{
+				handle_wan_down(data_wan_tether->is_sta);
+			}
+		}
+		break;
+
+	case IPA_HANDLE_WAN_DOWN_V6_TETHER:
+		IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_V6_TETHER event\n");
+		data_wan_tether = (ipacm_event_iface_up_tehter*)param;
+		if(data_wan_tether == NULL)
+		{
+			IPACMERR("No event data is found.\n");
+			return;
+		}
+		IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d\n", data_wan_tether->is_sta,
+					data_wan_tether->if_index_tether);
+		if (iface_ipa_index_query(data_wan_tether->if_index_tether) == ipa_if_num)
+		{
+			/* clean up v6 RT rules*/
+			IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_V6_TETHER in LAN-instance and need clean up client IPv6 address \n");
+			/* reset usb-client ipv6 rt-rules */
+			handle_lan_client_reset_rt(IPA_IP_v6);
+
+			if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
+			{
+				handle_wan_down_v6(data_wan_tether->is_sta);
+			}
+		}
+		break;
+#else
 	case IPA_HANDLE_WAN_UP:
 		IPACMDBG_H("Received IPA_HANDLE_WAN_UP event\n");
 
@@ -652,6 +760,7 @@
 			handle_wan_down_v6(data_wan->is_sta);
 		}
 		break;
+#endif
 
 	case IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT:
 		{
@@ -989,7 +1098,7 @@
 	case IPA_TETHERING_STATS_UPDATE_EVENT:
 	{
 		IPACMDBG_H("Received IPA_TETHERING_STATS_UPDATE_EVENT event.\n");
-		if (IPACM_Wan::isWanUP() || IPACM_Wan::isWanUP_V6())
+		if (IPACM_Wan::isWanUP(ipa_if_num) || IPACM_Wan::isWanUP_V6(ipa_if_num))
 		{
 			if(IPACM_Wan::backhaul_is_sta_mode == false) /* LTE */
 			{
@@ -2694,13 +2803,13 @@
 #endif
 
 	/* delete wan filter rule */
-	if (IPACM_Wan::isWanUP() && rx_prop != NULL)
+	if (IPACM_Wan::isWanUP(ipa_if_num) && rx_prop != NULL)
 	{
 		IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_is_sta_mode);
 		handle_wan_down(IPACM_Wan::backhaul_is_sta_mode);
 	}
 
-	if (IPACM_Wan::isWanUP_V6() && rx_prop != NULL)
+	if (IPACM_Wan::isWanUP_V6(ipa_if_num) && rx_prop != NULL)
 	{
 		IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_is_sta_mode);
 		handle_wan_down_v6(IPACM_Wan::backhaul_is_sta_mode);
@@ -3010,15 +3119,21 @@
 
 /* Delete private subnet*/
 #ifdef FEATURE_IPA_ANDROID
-if (ip_type != IPA_IP_v6)
-{
-	IPACMDBG_H("current IPACM private subnet_addr number(%d)\n", IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
-	IPACMDBG_H(" Delete IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
-	if(IPACM_Iface::ipacmcfg->DelPrivateSubnet(if_ipv4_subnet, ipa_if_num) == false)
+	if (ip_type != IPA_IP_v6)
 	{
-		IPACMERR(" can't Delete IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
+		IPACMDBG_H("current IPACM private subnet_addr number(%d)\n", IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
+		IPACMDBG_H(" Delete IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
+		if(IPACM_Iface::ipacmcfg->DelPrivateSubnet(if_ipv4_subnet, ipa_if_num) == false)
+		{
+			IPACMERR(" can't Delete IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
+		}
 	}
-}
+
+	/* reset the IPA-client pipe enum */
+	if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat != WAN_IF)
+	{
+		handle_tethering_client(true, IPACM_CLIENT_USB);
+	}
 #endif /* defined(FEATURE_IPA_ANDROID)*/
 fail:
 	if (odu_route_rule_v4_hdl != NULL)
@@ -3273,14 +3388,12 @@
 		IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
 		return IPACM_FAILURE;
 	}
-
 	if(m_filtering.DeleteFilteringHdls(ipv6_prefix_flt_rule_hdl, IPA_IP_v6, NUM_IPV6_PREFIX_FLT_RULE) == false)
 	{
 		close(fd);
 		return IPACM_FAILURE;
 	}
 	IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, NUM_IPV6_PREFIX_FLT_RULE);
-
 	if(is_sta_mode == false)
 	{
 		if (num_wan_ul_fl_rule_v6 > MAX_WAN_UL_FILTER_RULES)
@@ -3289,7 +3402,6 @@
 			close(fd);
 			return IPACM_FAILURE;
 		}
-
 		if (m_filtering.DeleteFilteringHdls(wan_ul_fl_rule_hdl_v6,
 			IPA_IP_v6, num_wan_ul_fl_rule_v6) == false)
 		{
@@ -3298,7 +3410,6 @@
 			return IPACM_FAILURE;
 		}
 		IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, num_wan_ul_fl_rule_v6);
-
 		memset(wan_ul_fl_rule_hdl_v6, 0, MAX_WAN_UL_FILTER_RULES * sizeof(uint32_t));
 		num_wan_ul_fl_rule_v6 = 0;
 
@@ -3312,7 +3423,6 @@
 		flt_index.retain_header = 0;
 		flt_index.embedded_call_mux_id_valid = 1;
 		flt_index.embedded_call_mux_id = IPACM_Iface::ipacmcfg->GetQmapId();
-
 		if(false == m_filtering.SendFilteringRuleIndex(&flt_index))
 		{
 			IPACMERR("Error sending filtering rule index, aborting...\n");
@@ -3331,7 +3441,6 @@
 		}
 		IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
 	}
-
 	close(fd);
 	return IPACM_SUCCESS;
 }
@@ -6952,3 +7061,63 @@
 	}
 	return IPACM_SUCCESS;
 }
+
+/*handle tether client */
+int IPACM_Lan::handle_tethering_client(bool reset, ipacm_client_enum ipa_client)
+{
+	int cnt, fd, ret = IPACM_SUCCESS;
+	int fd_wwan_ioctl = open(WWAN_QMI_IOCTL_DEVICE_NAME, O_RDWR);
+	wan_ioctl_set_tether_client_pipe tether_client;
+
+	if(fd_wwan_ioctl < 0)
+	{
+		IPACMERR("Failed to open %s.\n",WWAN_QMI_IOCTL_DEVICE_NAME);
+		return IPACM_FAILURE;
+	}
+
+	fd = open(IPA_DEVICE_NAME, O_RDWR);
+	if (fd < 0)
+	{
+		IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
+		close(fd_wwan_ioctl);
+		return IPACM_FAILURE;
+	}
+
+	memset(&tether_client, 0, sizeof(tether_client));
+	tether_client.reset_client = reset;
+	tether_client.ipa_client = ipa_client;
+
+	if(tx_prop != NULL)
+	{
+		tether_client.dl_dst_pipe_len = tx_prop->num_tx_props;
+		for (cnt = 0; cnt < tx_prop->num_tx_props; cnt++)
+		{
+			IPACMDBG_H("Tx(%d), dst_pipe: %d, ipa_pipe: %d\n",
+					cnt, tx_prop->tx[cnt].dst_pipe,
+						ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, tx_prop->tx[cnt].dst_pipe));
+			tether_client.dl_dst_pipe_list[cnt] = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, tx_prop->tx[cnt].dst_pipe);
+		}
+	}
+
+	if(rx_prop != NULL)
+	{
+		tether_client.ul_src_pipe_len = rx_prop->num_rx_props;
+		for (cnt = 0; cnt < rx_prop->num_rx_props; cnt++)
+		{
+			IPACMDBG_H("Rx(%d), src_pipe: %d, ipa_pipe: %d\n",
+					cnt, rx_prop->rx[cnt].src_pipe,
+						ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[cnt].src_pipe));
+			tether_client.ul_src_pipe_list[cnt] = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[cnt].src_pipe);
+		}
+	}
+
+	ret = ioctl(fd_wwan_ioctl, WAN_IOC_SET_TETHER_CLIENT_PIPE, &tether_client);
+	if (ret != 0)
+	{
+		IPACMERR("Failed set tether-client-pipe %p with ret %d\n ", &tether_client, ret);
+	}
+	IPACMDBG("Set tether-client-pipe %p\n", &tether_client);
+	close(fd);
+	close(fd_wwan_ioctl);
+	return ret;
+}
diff --git a/ipacm/src/IPACM_Main.cpp b/ipacm/src/IPACM_Main.cpp
index a86cfb8..67d9077 100644
--- a/ipacm/src/IPACM_Main.cpp
+++ b/ipacm/src/IPACM_Main.cpp
@@ -570,7 +570,7 @@
 			evt_data.event = IPA_LINK_DOWN_EVENT;
 			evt_data.evt_data = data_fid;
 			break;
-        /* Add for 8994 Android case */
+		/* Add for 8994 Android case */
 		case WAN_UPSTREAM_ROUTE_ADD:
 			memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_wan_msg));
 			IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_ADD name: %s, tethered name: %s\n", event_wan.upstream_ifname, event_wan.tethered_ifname);
@@ -581,8 +581,10 @@
 				return NULL;
 			}
 			ipa_get_if_index(event_wan.upstream_ifname, &(data_iptype->if_index));
+			ipa_get_if_index(event_wan.tethered_ifname, &(data_iptype->if_index_tether));
 			data_iptype->iptype = event_wan.ip;
-			IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_ADD: fid(%d) ip-type(%d)\n", data_iptype->if_index, data_iptype->iptype);
+			IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_ADD: fid(%d) tether_fid(%d) ip-type(%d)\n", data_iptype->if_index,
+					data_iptype->if_index_tether, data_iptype->iptype);
 			evt_data.event = IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT;
 			evt_data.evt_data = data_iptype;
 			break;
@@ -596,14 +598,15 @@
 				return NULL;
 			}
 			ipa_get_if_index(event_wan.upstream_ifname, &(data_iptype->if_index));
+			ipa_get_if_index(event_wan.tethered_ifname, &(data_iptype->if_index_tether));
 			data_iptype->iptype = event_wan.ip;
 			IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_DEL: fid(%d) ip-type(%d)\n", data_iptype->if_index, data_iptype->iptype);
 			evt_data.event = IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT;
 			evt_data.evt_data = data_iptype;
 			break;
-        /* End of adding for 8994 Android case */
+		/* End of adding for 8994 Android case */
 
-        /* Add for embms case */
+		/* Add for embms case */
 		case WAN_EMBMS_CONNECT:
 			memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_wan_msg));
 			IPACMDBG("Received WAN_EMBMS_CONNECT name: %s\n",event_wan.upstream_ifname);
diff --git a/ipacm/src/IPACM_Wan.cpp b/ipacm/src/IPACM_Wan.cpp
index 6381826..5e215ce 100644
--- a/ipacm/src/IPACM_Wan.cpp
+++ b/ipacm/src/IPACM_Wan.cpp
@@ -74,6 +74,14 @@
 
 uint32_t IPACM_Wan::backhaul_ipv6_prefix[2];
 
+#ifdef FEATURE_IPA_ANDROID
+int	IPACM_Wan::ipa_if_num_tether_v4_total = 0;
+int	IPACM_Wan::ipa_if_num_tether_v6_total = 0;
+
+int	IPACM_Wan::ipa_if_num_tether_v4[IPA_MAX_IFACE_ENTRIES];
+int	IPACM_Wan::ipa_if_num_tether_v6[IPA_MAX_IFACE_ENTRIES];
+#endif
+
 IPACM_Wan::IPACM_Wan(int iface_index,
 	ipacm_wan_iface_type is_sta_mode,
 	uint8_t *mac_addr) : IPACM_Iface(iface_index)
@@ -693,18 +701,27 @@
 			{
 				IPACMDBG_H("Received IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT (Android) for ip-type (%d)\n", data->iptype);
 				/* The special below condition is to handle default gateway */
-				if ((data->iptype == IPA_IP_v4) && (active_v4 == false) && (ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX))
+				if ((data->iptype == IPA_IP_v4) && (ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX))
 				{
-//					wan_v4_addr_gw = data->ipv4_addr_gw; /* android requires CnE change too */
-//					wan_v4_addr_gw_set = true;
-					IPACMDBG_H("adding routing table, dev (%s) ip-type(%d), default gw (%x)\n", dev_name,data->iptype, wan_v4_addr_gw);
-					handle_route_add_evt(data->iptype);
-
+					if (active_v4 == false)
+					{
+						IPACMDBG_H("adding routing table(upstream), dev (%s) ip-type(%d)\n", dev_name,data->iptype);
+						handle_route_add_evt(data->iptype);
+					}
+#ifdef FEATURE_IPA_ANDROID
+					post_wan_up_tether_evt(data->iptype, data->if_index_tether);
+#endif
 				}
-				else if ((data->iptype == IPA_IP_v6) && (active_v6 == false) && (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX))
+				else if ((data->iptype == IPA_IP_v6) && (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX))
 				{
-					IPACMDBG_H("\n get default v6 route (dst:00.00.00.00) upstream\n");
-				  	handle_route_add_evt(data->iptype);
+					if (active_v6 == false)
+					{
+						IPACMDBG_H("\n get default v6 route (dst:00.00.00.00) upstream\n");
+						handle_route_add_evt(data->iptype);
+					}
+#ifdef FEATURE_IPA_ANDROID
+					post_wan_up_tether_evt(data->iptype, data->if_index_tether);
+#endif
 				}
 			}
 			else /* double check if current default iface is not itself */
@@ -757,6 +774,15 @@
 				{
 					IPACMDBG_H("get del default v4 route (dst:0.0.0.0)\n");
 //					wan_v4_addr_gw_set = false; /* android requires CnE change too */
+#ifdef FEATURE_IPA_ANDROID
+					post_wan_down_tether_evt(data->iptype, data->if_index_tether);
+					/* no any ipv4 tether iface support*/
+					if(IPACM_Wan::ipa_if_num_tether_v4_total != 0)
+					{
+						IPACMDBG_H("still have tether ipv4 client on upsteam iface\n");
+						return;
+					}
+#endif
 					if(m_is_sta_mode == Q6_WAN)
 					{
 						del_wan_firewall_rule(IPA_IP_v4);
@@ -771,6 +797,15 @@
 				}
 				else if ((data->iptype == IPA_IP_v6) && (active_v6 == true))
 				{
+#ifdef FEATURE_IPA_ANDROID
+					post_wan_down_tether_evt(data->iptype, data->if_index_tether);
+					/* no any ipv6 tether iface support*/
+					if(IPACM_Wan::ipa_if_num_tether_v6_total != 0)
+					{
+						IPACMDBG_H("still have tether ipv6 client on upsteam iface\n");
+						return;
+					}
+#endif
 					if(m_is_sta_mode == Q6_WAN)
 					{
 						del_wan_firewall_rule(IPA_IP_v6);
@@ -1502,6 +1537,147 @@
 	return IPACM_SUCCESS;
 }
 
+#ifdef FEATURE_IPA_ANDROID
+/* wan default route/filter rule configuration */
+int IPACM_Wan::post_wan_up_tether_evt(ipa_ip_type iptype, int ipa_if_num_tether)
+{
+	ipacm_cmd_q_data evt_data;
+	ipacm_event_iface_up_tehter *wanup_data;
+
+	wanup_data = (ipacm_event_iface_up_tehter *)malloc(sizeof(ipacm_event_iface_up_tehter));
+	if (wanup_data == NULL)
+	{
+		IPACMERR("Unable to allocate memory\n");
+		return IPACM_FAILURE;
+	}
+	memset(wanup_data, 0, sizeof(ipacm_event_iface_up_tehter));
+
+	wanup_data->if_index_tether = ipa_if_num_tether;
+	if (m_is_sta_mode!=Q6_WAN)
+	{
+		wanup_data->is_sta = true;
+	}
+	else
+	{
+		wanup_data->is_sta = false;
+	}
+	IPACMDBG_H("Posting IPA_HANDLE_WAN_UP_TETHER with below information:\n");
+	IPACMDBG_H("tether_if_name:%s, is sta mode:%d\n",
+			IPACM_Iface::ipacmcfg->iface_table[iface_ipa_index_query(ipa_if_num_tether)].iface_name, wanup_data->is_sta);
+	memset(&evt_data, 0, sizeof(evt_data));
+
+	if (iptype == IPA_IP_v4)
+	{
+		evt_data.event = IPA_HANDLE_WAN_UP_TETHER;
+		/* Add support tether ifaces to its array*/
+		IPACM_Wan::ipa_if_num_tether_v4[IPACM_Wan::ipa_if_num_tether_v4_total] = ipa_if_num_tether;
+		IPACMDBG_H("adding tether iface(%s) ipa_if_num_tether_v4_total(%d)\n",
+			IPACM_Iface::ipacmcfg->iface_table[iface_ipa_index_query(ipa_if_num_tether)].iface_name,
+				IPACM_Wan::ipa_if_num_tether_v4_total);
+		IPACM_Wan::ipa_if_num_tether_v4_total++;
+	}
+	else
+	{
+		evt_data.event = IPA_HANDLE_WAN_UP_V6_TETHER;
+		memcpy(wanup_data->ipv6_prefix, ipv6_prefix, sizeof(wanup_data->ipv6_prefix));
+		/* Add support tether ifaces to its array*/
+		IPACM_Wan::ipa_if_num_tether_v6[IPACM_Wan::ipa_if_num_tether_v6_total] = ipa_if_num_tether;
+		IPACMDBG_H("adding tether iface(%s) ipa_if_num_tether_v6_total(%d)\n",
+			IPACM_Iface::ipacmcfg->iface_table[iface_ipa_index_query(ipa_if_num_tether)].iface_name,
+				IPACM_Wan::ipa_if_num_tether_v6_total);
+		IPACM_Wan::ipa_if_num_tether_v6_total++;
+	}
+		evt_data.evt_data = (void *)wanup_data;
+		IPACM_EvtDispatcher::PostEvt(&evt_data);
+
+	return IPACM_SUCCESS;
+}
+
+/* wan default route/filter rule configuration */
+int IPACM_Wan::post_wan_down_tether_evt(ipa_ip_type iptype, int ipa_if_num_tether)
+{
+	ipacm_cmd_q_data evt_data;
+	ipacm_event_iface_up_tehter *wandown_data;
+	int i, j;
+
+	wandown_data = (ipacm_event_iface_up_tehter *)malloc(sizeof(ipacm_event_iface_up_tehter));
+	if (wandown_data == NULL)
+	{
+		IPACMERR("Unable to allocate memory\n");
+		return IPACM_FAILURE;
+	}
+	memset(wandown_data, 0, sizeof(ipacm_event_iface_up_tehter));
+
+	wandown_data->if_index_tether = ipa_if_num_tether;
+	if (m_is_sta_mode!=Q6_WAN)
+	{
+		wandown_data->is_sta = true;
+	}
+	else
+	{
+		wandown_data->is_sta = false;
+	}
+	IPACMDBG_H("Posting IPA_HANDLE_WAN_DOWN_TETHER with below information:\n");
+	IPACMDBG_H("tether_if_name:%s, is sta mode:%d\n",
+			IPACM_Iface::ipacmcfg->iface_table[iface_ipa_index_query(ipa_if_num_tether)].iface_name, wandown_data->is_sta);
+	memset(&evt_data, 0, sizeof(evt_data));
+
+	if (iptype == IPA_IP_v4)
+	{
+		evt_data.event = IPA_HANDLE_WAN_DOWN_TETHER;
+		/* delete support tether ifaces to its array*/
+		for (i=0; i < IPACM_Wan::ipa_if_num_tether_v4_total; i++) //sky
+		{
+			if(IPACM_Wan::ipa_if_num_tether_v4[i] == ipa_if_num_tether)
+			{
+				IPACMDBG_H("Found tether client at position %d.\n", i);
+				break;
+			}
+		}
+		if(i == IPACM_Wan::ipa_if_num_tether_v4_total)
+		{
+			IPACMDBG_H("Not finding the tether client.\n");
+			free(wandown_data);
+			return IPACM_SUCCESS;
+		}
+		for(j = i+1; j < IPACM_Wan::ipa_if_num_tether_v4_total; j++)
+		{
+			IPACM_Wan::ipa_if_num_tether_v4[j-1] = IPACM_Wan::ipa_if_num_tether_v4[j];
+		}
+		IPACM_Wan::ipa_if_num_tether_v4_total--;
+		IPACMDBG_H("Now the total num of ipa_if_num_tether_v4_total is %d \n", IPACM_Wan::ipa_if_num_tether_v4_total);
+	}
+	else
+	{
+		evt_data.event = IPA_HANDLE_WAN_DOWN_V6_TETHER;
+		/* delete support tether ifaces to its array*/
+		for (i=0; i < IPACM_Wan::ipa_if_num_tether_v6_total; i++) //sky
+		{
+			if(IPACM_Wan::ipa_if_num_tether_v6[i] == ipa_if_num_tether)
+			{
+				IPACMDBG_H("Found tether client at position %d.\n", i);
+				break;
+			}
+		}
+		if(i == IPACM_Wan::ipa_if_num_tether_v6_total)
+		{
+			IPACMDBG_H("Not finding the tether client.\n");
+			free(wandown_data);
+			return IPACM_SUCCESS;
+		}
+		for(j = i+1; j < IPACM_Wan::ipa_if_num_tether_v6_total; j++)
+		{
+			IPACM_Wan::ipa_if_num_tether_v6[j-1] = IPACM_Wan::ipa_if_num_tether_v6[j];
+		}
+		IPACM_Wan::ipa_if_num_tether_v6_total--;
+		IPACMDBG_H("Now the total num of ipa_if_num_tether_v6_total is %d \n", IPACM_Wan::ipa_if_num_tether_v6_total);
+	}
+		evt_data.evt_data = (void *)wandown_data;
+		IPACM_EvtDispatcher::PostEvt(&evt_data);
+	return IPACM_SUCCESS;
+}
+#endif
+
 /* construct complete ethernet header */
 int IPACM_Wan::handle_sta_header_add_evt()
 {
diff --git a/ipacm/src/IPACM_Wlan.cpp b/ipacm/src/IPACM_Wlan.cpp
index 075da13..530e2bf 100644
--- a/ipacm/src/IPACM_Wlan.cpp
+++ b/ipacm/src/IPACM_Wlan.cpp
@@ -189,6 +189,14 @@
 		}
 	}
 #endif
+
+#ifdef FEATURE_IPA_ANDROID
+	/* set the IPA-client pipe enum */
+	if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == WLAN_IF)
+	{
+		handle_tethering_client(false, IPACM_CLIENT_WLAN);
+	}
+#endif
 	return;
 }
 
@@ -212,6 +220,7 @@
 	int wlan_index;
 	ipacm_ext_prop* ext_prop;
 	ipacm_event_iface_up* data_wan;
+	ipacm_event_iface_up_tehter* data_wan_tether;
 
 	switch (event)
 	{
@@ -342,7 +351,7 @@
 					}
 #endif
 
-					if (IPACM_Wan::isWanUP())
+					if (IPACM_Wan::isWanUP(ipa_if_num))
 					{
 						if(data->iptype == IPA_IP_v4 || data->iptype == IPA_IP_MAX)
 						{
@@ -359,7 +368,7 @@
 						}
 					}
 
-					if(IPACM_Wan::isWanUP_V6())
+					if(IPACM_Wan::isWanUP_V6(ipa_if_num))
 					{
 						if((data->iptype == IPA_IP_v6 || data->iptype == IPA_IP_MAX) && num_dft_rt_v6 == 1)
 						{
@@ -391,7 +400,128 @@
 			}
 		}
 		break;
+#ifdef FEATURE_IPA_ANDROID
+	case IPA_HANDLE_WAN_UP_TETHER:
+		IPACMDBG_H("Received IPA_HANDLE_WAN_UP_TETHER event\n");
 
+		data_wan_tether = (ipacm_event_iface_up_tehter*)param;
+		if(data_wan_tether == NULL)
+		{
+			IPACMERR("No event data is found.\n");
+			return;
+		}
+		IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d\n", data_wan_tether->is_sta,
+					data_wan_tether->if_index_tether);
+		if (iface_ipa_index_query(data_wan_tether->if_index_tether) == ipa_if_num)
+		{
+			if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
+			{
+				if(data_wan_tether->is_sta == false)
+				{
+					ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
+					IPACM_Lan::handle_wan_up_ex(ext_prop, IPA_IP_v4, 0);
+				}
+				else
+				{
+					IPACM_Lan::handle_wan_up(IPA_IP_v4);
+				}
+			}
+		}
+		break;
+
+	case IPA_HANDLE_WAN_UP_V6_TETHER:
+		IPACMDBG_H("Received IPA_HANDLE_WAN_UP_V6_TETHER event\n");
+
+		data_wan_tether = (ipacm_event_iface_up_tehter*)param;
+		if(data_wan_tether == NULL)
+		{
+			IPACMERR("No event data is found.\n");
+			return;
+		}
+		IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d\n", data_wan_tether->is_sta,
+					data_wan_tether->if_index_tether);
+		if (iface_ipa_index_query(data_wan_tether->if_index_tether) == ipa_if_num)
+		{
+			if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
+			{
+				if(wlan_ap_index == 0) //install ipv6 prefix rule only once
+				{
+					install_ipv6_prefix_flt_rule(data_wan_tether->ipv6_prefix);
+				}
+				if(data_wan_tether->is_sta == false)
+				{
+					ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
+					IPACM_Lan::handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
+				}
+				else
+				{
+					IPACM_Lan::handle_wan_up(IPA_IP_v6);
+				}
+			}
+		}
+		break;
+
+	case IPA_HANDLE_WAN_DOWN_TETHER:
+		IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_TETHER event\n");
+		data_wan_tether = (ipacm_event_iface_up_tehter*)param;
+		if(data_wan_tether == NULL)
+		{
+			IPACMERR("No event data is found.\n");
+			return;
+		}
+		IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d, itself %d\n", data_wan_tether->is_sta,
+					iface_ipa_index_query(data_wan_tether->if_index_tether),
+					ipa_if_num);
+		if (iface_ipa_index_query(data_wan_tether->if_index_tether) == ipa_if_num)
+		{
+			if(data_wan_tether->is_sta == false && wlan_ap_index > 0)
+			{
+				IPACMDBG_H("This is not the first AP instance and not STA mode, ignore WAN_DOWN event.\n");
+				return;
+			}
+			if (rx_prop != NULL)
+			{
+				if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
+				{
+					handle_wan_down(data_wan_tether->is_sta);
+				}
+			}
+		}
+		break;
+
+	case IPA_HANDLE_WAN_DOWN_V6_TETHER:
+		IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_V6_TETHER event\n");
+		data_wan_tether = (ipacm_event_iface_up_tehter*)param;
+		if(data_wan_tether == NULL)
+		{
+			IPACMERR("No event data is found.\n");
+			return;
+		}
+		IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d, itself %d\n", data_wan_tether->is_sta,
+					iface_ipa_index_query(data_wan_tether->if_index_tether),
+					ipa_if_num);
+		if (iface_ipa_index_query(data_wan_tether->if_index_tether) == ipa_if_num)
+		{
+			/* clean up v6 RT rules*/
+			IPACMDBG_H("Received IPA_WAN_V6_DOWN in WLAN-instance and need clean up client IPv6 address \n");
+			/* reset wifi-client ipv6 rt-rules */
+			handle_wlan_client_reset_rt(IPA_IP_v6);
+
+			if(data_wan_tether->is_sta == false && wlan_ap_index > 0)
+			{
+				IPACMDBG_H("This is not the first AP instance and not STA mode, ignore WAN_DOWN event.\n");
+				return;
+			}
+			if (rx_prop != NULL)
+			{
+				if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
+				{
+					handle_wan_down_v6(data_wan_tether->is_sta);
+				}
+			}
+		}
+		break;
+#else
 	case IPA_HANDLE_WAN_UP:
 		IPACMDBG_H("Received IPA_HANDLE_WAN_UP event\n");
 
@@ -493,6 +623,7 @@
 			}
 		}
 		break;
+#endif
 
 	case IPA_WLAN_CLIENT_ADD_EVENT_EX:
 		{
@@ -873,7 +1004,7 @@
 	case IPA_TETHERING_STATS_UPDATE_EVENT:
 	{
 		IPACMDBG_H("Received IPA_TETHERING_STATS_UPDATE_EVENT event.\n");
-		if (IPACM_Wan::isWanUP() || IPACM_Wan::isWanUP_V6())
+		if (IPACM_Wan::isWanUP(ipa_if_num) || IPACM_Wan::isWanUP_V6(ipa_if_num))
 		{
 			if(IPACM_Wan::backhaul_is_sta_mode == false) /* LTE */
 			{
@@ -2337,13 +2468,13 @@
 #endif
 
 	/* delete wan filter rule */
-	if (IPACM_Wan::isWanUP() && rx_prop != NULL)
+	if (IPACM_Wan::isWanUP(ipa_if_num) && rx_prop != NULL)
 	{
 		IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_is_sta_mode);
 		IPACM_Lan::handle_wan_down(IPACM_Wan::backhaul_is_sta_mode);
 	}
 
-	if (IPACM_Wan::isWanUP_V6() && rx_prop != NULL)
+	if (IPACM_Wan::isWanUP_V6(ipa_if_num) && rx_prop != NULL)
 	{
 		IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_is_sta_mode);
 		IPACM_Lan::handle_wan_down_v6(IPACM_Wan::backhaul_is_sta_mode);
@@ -2631,6 +2762,8 @@
 			IPACMERR(" can't Delete IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
 		}
 	}
+	/* reset the IPA-client pipe enum */
+	handle_tethering_client(true, IPACM_CLIENT_WLAN);
 #endif /* defined(FEATURE_IPA_ANDROID)*/
 
 fail:
diff --git a/ipanat/src/ipa_nat_drvi.c b/ipanat/src/ipa_nat_drvi.c
index 8ba2bdb..cfda3e3 100644
--- a/ipanat/src/ipa_nat_drvi.c
+++ b/ipanat/src/ipa_nat_drvi.c
@@ -823,7 +823,7 @@
 																 prot, flags,
 																 fd, offset);
 #endif
-	if (NULL == ipv4_rules_addr) {
+	if (MAP_FAILED  == ipv4_rules_addr) {
 		perror("unable to mmap the memory\n");
 		return -EINVAL;
 	}