Merge "IPACM: Move ipacm.pid file to /data/misc/ipa"
diff --git a/ipacm/inc/IPACM_Defs.h b/ipacm/inc/IPACM_Defs.h
index 20cde8d..a956643 100644
--- a/ipacm/inc/IPACM_Defs.h
+++ b/ipacm/inc/IPACM_Defs.h
@@ -213,7 +213,7 @@
 	int if_index;
 	uint32_t  ipv4_addr;
 	uint32_t  ipv6_addr[4];
-	uint8_t mac_addr[6];
+	uint8_t mac_addr[IPA_MAC_ADDR_SIZE];
 } ipacm_event_data_all;
 
 class IPACM_Lan;
@@ -261,7 +261,7 @@
 typedef struct _ipacm_event_data_mac
 {
 	int if_index;
-	uint8_t mac_addr[6];
+	uint8_t mac_addr[IPA_MAC_ADDR_SIZE];
 } ipacm_event_data_mac;
 
 typedef struct
@@ -287,4 +287,11 @@
 	ECM_WAN
 } ipacm_wan_iface_type;
 
+typedef struct _ipacm_ifacemgr_data
+{
+	int if_index;
+	ipacm_wan_iface_type if_type;
+	uint8_t mac_addr[IPA_MAC_ADDR_SIZE];
+}ipacm_ifacemgr_data;
+
 #endif /* IPA_CM_DEFS_H */
diff --git a/ipacm/inc/IPACM_IfaceManager.h b/ipacm/inc/IPACM_IfaceManager.h
index e621067..e65c5d5 100644
--- a/ipacm/inc/IPACM_IfaceManager.h
+++ b/ipacm/inc/IPACM_IfaceManager.h
@@ -77,7 +77,7 @@
 
 
 private:
-	int create_iface_instance(int if_index, ipacm_wan_iface_type is_sta_mode);
+	int create_iface_instance(ipacm_ifacemgr_data *);
 
     /* api to register instances */
 	int registr(int ipa_if_index, IPACM_Listener *obj);
diff --git a/ipacm/inc/IPACM_Wan.h b/ipacm/inc/IPACM_Wan.h
index 7888791..e3025b5 100644
--- a/ipacm/inc/IPACM_Wan.h
+++ b/ipacm/inc/IPACM_Wan.h
@@ -87,7 +87,7 @@
 	static bool wan_up;
 	static bool wan_up_v6;
 
-	IPACM_Wan(int iface_index, ipacm_wan_iface_type is_sta_mode);
+	IPACM_Wan(int, ipacm_wan_iface_type, uint8_t *);
 	virtual ~IPACM_Wan();
 
 	static bool isWanUP()
@@ -137,6 +137,9 @@
 	bool header_set_v6;
 	bool header_partial_default_wan_v4;
 	bool header_partial_default_wan_v6;
+	uint8_t ext_router_mac_addr[IPA_MAC_ADDR_SIZE];
+	uint16_t eth2_ofst_v4;
+	uint16_t eth2_ofst_v6;
 
 	static int num_ipv4_modem_pdn;
 
@@ -273,7 +276,7 @@
 	int handle_route_add_evt(ipa_ip_type iptype);
 
 	/* construct complete ethernet header */
-	int handle_header_add_evt(uint8_t mac_addr[6]);
+	int handle_header_add_evt(uint8_t *mac_addr);
 
 	int config_dft_firewall_rules(ipa_ip_type iptype);
 
diff --git a/ipacm/src/IPACM_Config.cpp b/ipacm/src/IPACM_Config.cpp
index 997f64e..4fa7a30 100644
--- a/ipacm/src/IPACM_Config.cpp
+++ b/ipacm/src/IPACM_Config.cpp
@@ -285,6 +285,10 @@
 	ipa_rm_tbl[2].producer_rm2 = IPA_RM_RESOURCE_USB_PROD;
 	ipa_rm_tbl[2].consumer_rm2 = IPA_RM_RESOURCE_WLAN_CONS;
 
+	IPACMDBG_H(" depend MAP-0 rm index %d to rm index: %d \n", IPA_RM_RESOURCE_WLAN_PROD, IPA_RM_RESOURCE_Q6_CONS);
+	IPACMDBG_H(" depend MAP-1 rm index %d to rm index: %d \n", IPA_RM_RESOURCE_USB_PROD, IPA_RM_RESOURCE_Q6_CONS);
+	IPACMDBG_H(" depend MAP-2 rm index %d to rm index: %d \n", IPA_RM_RESOURCE_WLAN_PROD, IPA_RM_RESOURCE_USB_CONS);
+
 fail:
 	if (cfg != NULL)
 	{
@@ -413,6 +417,7 @@
 	int retval = 0;
 	struct ipa_ioc_rm_dependency dep;
 
+	IPACMDBG_H(" Got rm add-depend index : %d \n", rm1);
 	/* ipa_rm_a2_check: IPA_RM_RESOURCE_Q6_CONS*/
 	if(rm1 == IPA_RM_RESOURCE_Q6_CONS)
 	{
@@ -520,6 +525,7 @@
 	int retval = 0;
 	struct ipa_ioc_rm_dependency dep;
 
+	IPACMDBG_H(" Got rm del-depend index : %d \n", rm1);
 	/* ipa_rm_a2_check: IPA_RM_RESOURCE_Q6_CONS*/
 	if(rm1 == IPA_RM_RESOURCE_Q6_CONS)
 	{
diff --git a/ipacm/src/IPACM_Iface.cpp b/ipacm/src/IPACM_Iface.cpp
index a2be272..2494e99 100644
--- a/ipacm/src/IPACM_Iface.cpp
+++ b/ipacm/src/IPACM_Iface.cpp
@@ -659,27 +659,35 @@
 	}
 
     /* ADD corresponding ipa_rm_resource_name of RX-endpoint before adding all IPV4V6 FT-rules */
-	if(rx_prop != NULL)
+	if((IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat== WAN_IF) || (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat== EMBMS_IF))
 	{
-	    IPACM_Iface::ipacmcfg->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe],false);
-		IPACMDBG_H(" add producer dependency from %s with registered rx-prop\n", dev_name);
+		IPACMDBG_H(" NOT add producer dependency on dev %s with registered rx-prop cat:%d \n", dev_name, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat);
 	}
 	else
 	{
-	     /* only wlan may take software-path, not register Rx-property*/
-	        if(strcmp(dev_name,dev_wlan0) == 0 || strcmp(dev_name,dev_wlan1) == 0)
-	  {
-	       IPACM_Iface::ipacmcfg->AddRmDepend(IPA_RM_RESOURCE_HSIC_PROD,true);
-		    IPACMDBG_H(" add producer dependency from %s without registered rx-prop \n", dev_name);
-	     }
-
-	     if(strcmp(dev_name,dev_ecm0) == 0)
-	     {
-	       IPACM_Iface::ipacmcfg->AddRmDepend(IPA_RM_RESOURCE_USB_PROD,true);
-		    IPACMDBG_H(" add producer dependency from %s without registered rx-prop \n", dev_name);
-	  }
+		if(rx_prop != NULL)
+		{
+			IPACMDBG_H("dev %s add producer dependency\n", dev_name);
+			IPACMDBG_H("depend Got pipe %d rm index : %d \n", rx_prop->rx[0].src_pipe, IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe]);
+			IPACM_Iface::ipacmcfg->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe],false);
+		}
+		else
+		{
+			/* only wlan may take software-path, not register Rx-property*/
+			if(strcmp(dev_name,dev_wlan0) == 0 || strcmp(dev_name,dev_wlan1) == 0)
+			{
+				IPACMDBG_H("dev %s add producer dependency\n", dev_name);
+				IPACMDBG_H("depend Got piperm index : %d \n", IPA_RM_RESOURCE_HSIC_PROD);
+				IPACM_Iface::ipacmcfg->AddRmDepend(IPA_RM_RESOURCE_HSIC_PROD,true);
+			}
+			if(strcmp(dev_name,dev_ecm0) == 0)
+			{
+				IPACMDBG_H("dev %s add producer dependency\n", dev_name);
+				IPACMDBG_H("depend Got piperm index : %d \n", IPA_RM_RESOURCE_USB_PROD);
+				IPACM_Iface::ipacmcfg->AddRmDepend(IPA_RM_RESOURCE_USB_PROD,true);
+			}
+		}
 	}
-
 	if (rx_prop == NULL)
 	{
 		IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
diff --git a/ipacm/src/IPACM_IfaceManager.cpp b/ipacm/src/IPACM_IfaceManager.cpp
index d38a58e..0c61833 100644
--- a/ipacm/src/IPACM_IfaceManager.cpp
+++ b/ipacm/src/IPACM_IfaceManager.cpp
@@ -68,6 +68,9 @@
 {
 	int ipa_interface_index;
 	ipacm_event_data_fid *evt_data = (ipacm_event_data_fid *)param;
+	ipacm_event_data_mac *StaData = (ipacm_event_data_mac *)param;
+	ipacm_ifacemgr_data ifmgr_data = {0};
+
 	switch(event)
 	{
 		case IPA_CFG_CHANGE_EVENT:
@@ -85,7 +88,9 @@
 			else if(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat == WAN_IF)
 			{
 				IPACMDBG_H("WAN-LTE (%s) link up, iface: %d: \n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,evt_data->if_index);
-				create_iface_instance(evt_data->if_index, Q6_WAN);
+				ifmgr_data.if_index = evt_data->if_index;
+				ifmgr_data.if_type = Q6_WAN;
+				create_iface_instance(&ifmgr_data);
 			}
 			break;
 
@@ -95,12 +100,16 @@
 			if(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat == WAN_IF)
 			{
 				/* usb-backhaul using sta_mode ECM_WAN*/
-				IPACMDBG_H("WAN-usb (%s) link up, iface: %d: \n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,evt_data->if_index);
-				create_iface_instance(evt_data->if_index, ECM_WAN);
+				IPACMDBG_H("WAN-usb (%s) link up, iface: %d: \n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name, evt_data->if_index);
+				ifmgr_data.if_index = evt_data->if_index;
+				ifmgr_data.if_type = ECM_WAN;
+				create_iface_instance(&ifmgr_data);
 			}
 			else
 			{
-				create_iface_instance(evt_data->if_index, Q6_WAN);
+				ifmgr_data.if_index = evt_data->if_index;
+				ifmgr_data.if_type = Q6_WAN;
+				create_iface_instance(&ifmgr_data);
 			}
 			break;
 
@@ -109,9 +118,11 @@
 			/* change iface category from unknown to WLAN_IF */
 			if(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat == UNKNOWN_IF)
 			{
-				IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat=WLAN_IF;
+				IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat = WLAN_IF;
 				IPACMDBG_H("WLAN AP (%s) link up, iface: %d: \n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,evt_data->if_index);
-				create_iface_instance(evt_data->if_index, Q6_WAN);
+				ifmgr_data.if_index = evt_data->if_index;
+				ifmgr_data.if_type = Q6_WAN;
+				create_iface_instance(&ifmgr_data);
 			}
 			else
 			{
@@ -120,18 +131,25 @@
 			break;
 
 		case IPA_WLAN_STA_LINK_UP_EVENT:
-			ipa_interface_index = IPACM_Iface::iface_ipa_index_query(evt_data->if_index);
+			ipa_interface_index = IPACM_Iface::iface_ipa_index_query(StaData->if_index);
 			/* change iface category from unknown to WAN_IF */
-			if(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat==UNKNOWN_IF)
+			if(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat == UNKNOWN_IF)
 			{
 				/* wlan-backhaul using sta_mode WLAN_WAN */
-				IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat=WAN_IF;
-				IPACMDBG_H("WLAN STA (%s) link up, iface: %d: \n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,evt_data->if_index);
-				create_iface_instance(evt_data->if_index, WLAN_WAN);
+				IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat = WAN_IF;
+				IPACMDBG_H("WLAN STA (%s) link up, iface: %d: \n",
+				IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name, StaData->if_index);
+
+				ifmgr_data.if_index = StaData->if_index;
+				ifmgr_data.if_type = WLAN_WAN;
+				memcpy(ifmgr_data.mac_addr, StaData->mac_addr, sizeof(ifmgr_data.mac_addr));
+				create_iface_instance(&ifmgr_data);
 			}
 			else
 			{
-				IPACMDBG_H("iface %s already up and act as %d mode: \n",IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat);
+				IPACMDBG_H("iface %s already up and act as %d mode: \n",
+				IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,
+						IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat);
 			}
 			break;
 
@@ -146,7 +164,9 @@
 			{
 				IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat=EMBMS_IF;
 				IPACMDBG("WAN eMBMS (%s) link up, iface: %d: \n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,evt_data->if_index);
-				create_iface_instance(evt_data->if_index, Q6_WAN);
+				ifmgr_data.if_index = StaData->if_index;
+				ifmgr_data.if_type = Q6_WAN;
+				create_iface_instance(&ifmgr_data);
 			}
 			else
 			{
@@ -161,8 +181,11 @@
 	return;
 }
 
-int IPACM_IfaceManager::create_iface_instance(int if_index, ipacm_wan_iface_type is_sta_mode)
+int IPACM_IfaceManager::create_iface_instance(ipacm_ifacemgr_data *param)
 {
+	int if_index = param->if_index;
+	ipacm_wan_iface_type is_sta_mode = param->if_type;
+
 	int ipa_interface_index;
 	ipa_interface_index = IPACM_Iface::iface_ipa_index_query(if_index);
 
@@ -298,13 +321,21 @@
 				if((IPACM_Iface::ipacmcfg->ipacm_odu_enable == false) || (IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == true))
 				{
 					IPACMDBG_H("Creating Wan interface\n");
-					IPACM_Wan *w = new IPACM_Wan(ipa_interface_index, is_sta_mode);
+					IPACM_Wan *w;
+					if(is_sta_mode == WLAN_WAN)
+					{
+						w = new IPACM_Wan(ipa_interface_index, is_sta_mode, param->mac_addr);
+					}
+					else
+					{
+						w = new IPACM_Wan(ipa_interface_index, is_sta_mode, NULL);
+					}
 					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_ADD_EVENT, w);
 #else/* defined(FEATURE_IPA_ANDROID) */
-				IPACM_EvtDispatcher::registr(IPA_ROUTE_ADD_EVENT, w);
-				IPACM_EvtDispatcher::registr(IPA_ROUTE_DEL_EVENT, w);
+					IPACM_EvtDispatcher::registr(IPA_ROUTE_ADD_EVENT, w);
+					IPACM_EvtDispatcher::registr(IPA_ROUTE_DEL_EVENT, w);
 #endif /* not defined(FEATURE_IPA_ANDROID)*/
 					IPACM_EvtDispatcher::registr(IPA_FIREWALL_CHANGE_EVENT, w);
 					IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, w);
@@ -331,7 +362,7 @@
 		case EMBMS_IF:
 			{
 				IPACMDBG("Creating Wan-eMBSM interface\n");
-				IPACM_Wan *embms = new IPACM_Wan(ipa_interface_index, is_sta_mode);
+				IPACM_Wan *embms = new IPACM_Wan(ipa_interface_index, is_sta_mode, NULL);
 				IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, embms);
 				IPACMDBG("ipa_WAN (%s):ipa_index (%d) instance open/registr ok\n", embms->dev_name, embms->ipa_if_num);
 				registr(ipa_interface_index, embms);
diff --git a/ipacm/src/IPACM_Lan.cpp b/ipacm/src/IPACM_Lan.cpp
index 44ed609..3cb41d4 100644
--- a/ipacm/src/IPACM_Lan.cpp
+++ b/ipacm/src/IPACM_Lan.cpp
@@ -1495,6 +1495,8 @@
 	{
 
         /* Add corresponding ipa_rm_resource_name of TX-endpoint up before IPV6 RT-rule set */
+	IPACMDBG_H("dev %s add producer dependency\n", dev_name);
+	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->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false);
 
 		rt_rule = (struct ipa_ioc_add_rt_rule *)
@@ -2080,8 +2082,10 @@
 	/* Del RM dependency */
 	if(num_eth_client == 0)
 	{
-	   /* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete all IPV4V6 RT-rule*/
-	   IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]);
+		/* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete all IPV4V6 RT-rule*/
+		IPACMDBG_H("dev %s add producer dependency\n", dev_name);
+		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]);
 	}
 
 	return IPACM_SUCCESS;
@@ -2317,6 +2321,8 @@
 	IPACMDBG_H("Free ecm clients cache\n");
 
 	/* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete all IPV4V6 RT-rule */
+	IPACMDBG_H("dev %s add producer dependency\n", dev_name);
+	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 */
@@ -2353,9 +2359,11 @@
 	/* Delete corresponding ipa_rm_resource_name of RX-endpoint after delete all IPV4V6 FT-rule */
 	if (rx_prop != NULL)
 	{
+		IPACMDBG_H("dev %s add producer dependency\n", dev_name);
+		IPACMDBG_H("depend Got pipe %d rm index : %d \n", rx_prop->rx[0].src_pipe, IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe]);
+		IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe]);
+		IPACMDBG_H("Finished delete dependency \n ");
 		free(rx_prop);
-	IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe]);
-	IPACMDBG_H("Finished delete dependency \n ");
 	}
 
 	if (eth_client != NULL)
diff --git a/ipacm/src/IPACM_Main.cpp b/ipacm/src/IPACM_Main.cpp
index 37f2b7b..d554bac 100644
--- a/ipacm/src/IPACM_Main.cpp
+++ b/ipacm/src/IPACM_Main.cpp
@@ -351,15 +351,18 @@
 			IPACMDBG_H("STA Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
 							 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
 							 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
-                        data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
-			if(data_fid == NULL)
+			data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
+			if(data == NULL)
 			{
 				IPACMERR("unable to allocate memory for event_wlan data_fid\n");
 				return NULL;
 			}
-			ipa_get_if_index(event_wlan->name, &(data_fid->if_index));
+			memcpy(data->mac_addr,
+				 event_wlan->mac_addr,
+				 sizeof(event_wlan->mac_addr));
+			ipa_get_if_index(event_wlan->name, &(data->if_index));
 			evt_data.event = IPA_WLAN_STA_LINK_UP_EVENT;
-			evt_data.evt_data = data_fid;
+			evt_data.evt_data = data;
 			break;
 
 		case WLAN_STA_DISCONNECT:
diff --git a/ipacm/src/IPACM_Wan.cpp b/ipacm/src/IPACM_Wan.cpp
index aa39d6c..150b24c 100644
--- a/ipacm/src/IPACM_Wan.cpp
+++ b/ipacm/src/IPACM_Wan.cpp
@@ -69,7 +69,9 @@
 
 uint32_t IPACM_Wan::backhaul_ipv6_prefix[2];
 
-IPACM_Wan::IPACM_Wan(int iface_index, ipacm_wan_iface_type is_sta_mode) : IPACM_Iface(iface_index)
+IPACM_Wan::IPACM_Wan(int iface_index,
+       ipacm_wan_iface_type is_sta_mode,
+       uint8_t *mac_addr) : IPACM_Iface(iface_index)
 {
 	num_firewall_v4 = 0;
 	num_firewall_v6 = 0;
@@ -123,6 +125,12 @@
 		IPACMDBG_H("The new WAN interface is WLAN STA.\n");
 	}
 
+	if(m_is_sta_mode == WLAN_WAN)
+	{
+		memcpy(ext_router_mac_addr, mac_addr,
+			sizeof(ext_router_mac_addr));
+	}
+
 	m_fd_ipa = open(IPA_DEVICE_NAME, O_RDWR);
 	if(0 == m_fd_ipa)
 	{
@@ -137,7 +145,9 @@
 		/* Add corresponding ipa_rm_resource_name of TX-endpoint up before IPV6 RT-rule set */
 		if(tx_prop != NULL)
 		{
-        		IPACM_Iface::ipacmcfg->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false);
+			IPACMDBG_H("dev %s add producer dependency\n", dev_name);
+			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->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false);
 		}
 	}
 	else
@@ -341,29 +351,29 @@
 		rt_rule->commit = 1;
 		rt_rule->num_rules = NUM_RULES;
 		rt_rule->ip = data->iptype;
-	    rt_rule_entry = &rt_rule->rules[0];
-	    rt_rule_entry->at_rear = false;
-	    rt_rule_entry->rule.dst = iface_query->excp_pipe;  //go to A5
-	    rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
+		rt_rule_entry = &rt_rule->rules[0];
+		rt_rule_entry->at_rear = false;
+		rt_rule_entry->rule.dst = iface_query->excp_pipe;  //go to A5
+		rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
 		/* still need setup v4 default routing rule to A5*/
 		strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name);
 		rt_rule_entry->rule.attrib.u.v4.dst_addr      = data->ipv4_addr;
 		rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
 
-	    if (false == m_routing.AddRoutingRule(rt_rule))
-	    {
-	    	IPACMERR("Routing rule addition failed!\n");
-	    	res = IPACM_FAILURE;
-	    	goto fail;
-	    }
-	    else if (rt_rule_entry->status)
+		if (false == m_routing.AddRoutingRule(rt_rule))
 		{
-	    	IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
-	    	res = rt_rule_entry->status;
-	    	goto fail;
-	    }
+			IPACMERR("Routing rule addition failed!\n");
+			res = IPACM_FAILURE;
+			goto fail;
+		}
+		else if (rt_rule_entry->status)
+		{
+			IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
+			res = rt_rule_entry->status;
+			goto fail;
+		}
 		dft_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl;
-        IPACMDBG_H("ipv4 wan iface rt-rule hdll=0x%x\n", dft_rt_rule_hdl[0]);
+		IPACMDBG_H("ipv4 wan iface rt-rule hdll=0x%x\n", dft_rt_rule_hdl[0]);
 			/* initial multicast/broadcast/fragment filter rule */
 
 		if(m_is_sta_mode == Q6_WAN)
@@ -382,7 +392,7 @@
 		IPACMDBG_H("Receved wan address:0x%x\n",wan_v4_addr);
 	}
 
-    IPACMDBG_H("number of default route rules %d\n", num_dft_rt_v6);
+	IPACMDBG_H("number of default route rules %d\n", num_dft_rt_v6);
 
 fail:
 	free(rt_rule);
@@ -408,7 +418,7 @@
 					handle_down_evt();
 					/* reset the STA-iface category to unknown */
 					IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat = UNKNOWN_IF;
-					IPACMDBG_H("ipa_WAN (%s):ipa_index (%d) instance close \n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, ipa_if_num);
+					IPACMDBG_H("IPA_WAN_STA (%s):ipa_index (%d) instance close \n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, ipa_if_num);
 					IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface
 					delete this;
 					return;
@@ -462,7 +472,7 @@
 				{
 					IPACMDBG_H("Received IPA_LINK_DOWN_EVENT\n");
 					handle_down_evt_ex();
-					IPACMDBG_H("ipa_WAN (%s):ipa_index (%d) instance close \n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, ipa_if_num);
+					IPACMDBG_H("IPA_WAN_Q6 (%s):ipa_index (%d) instance close \n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, ipa_if_num);
 					IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface
 					delete this;
 					return;
@@ -470,9 +480,10 @@
 			}
 			else if (m_is_sta_mode == ECM_WAN)
 			{
-				IPACMDBG("Received link-down (wan_mode:%d)\n", m_is_sta_mode);
+				IPACMDBG_H("Received IPA_LINK_DOWN_EVENT(wan_mode:%d)\n", m_is_sta_mode);
 				/* delete previous instance */
 				handle_down_evt();
+				IPACMDBG_H("IPA_WAN_CRADLE (%s):ipa_index (%d) instance close \n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, ipa_if_num);
 				IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface
 				delete this;
 				return;
@@ -729,14 +740,38 @@
 			if (ipa_interface_index == ipa_if_num)
 			{
 				IPACMDBG_H("Received IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT in STA mode\n");
-				handle_header_add_evt(data->mac_addr);
 
-				/* new */
+				if (m_is_sta_mode == WLAN_WAN)
+				{
+					handle_header_add_evt(ext_router_mac_addr);
+					if (data->iptype == IPA_IP_v4 && data->ipv4_addr == wan_v4_addr)
+					{
+						IPACMDBG_H("Ignore IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT in STA mode\n");
+						IPACMDBG_H("for its own ipv4 address\n");
+						return;
+					}
+					else if (data->iptype == IPA_IP_v6)
+					{
+						for (int num_ipv6_addr = 0; num_ipv6_addr < num_dft_rt_v6; num_ipv6_addr++)
+						{
+							if ((ipv6_addr[num_ipv6_addr][0] == data->ipv6_addr[0]) &&
+								(ipv6_addr[num_ipv6_addr][1] == data->ipv6_addr[1]) &&
+								(ipv6_addr[num_ipv6_addr][2] == data->ipv6_addr[2]) &&
+								(ipv6_addr[num_ipv6_addr][3] == data->ipv6_addr[3]))
+							{
+								IPACMDBG_H("Ignore IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT in STA mode\n");
+								IPACMDBG_H("for its own ipv6 address\n");
+								return;
+							}
+						}
+					}
+				}
+
 				IPACMDBG_H("wan-iface got client \n");
 				/* first construc WAN-client full header */
 				if(memcmp(data->mac_addr,
-									invalid_mac,
-									sizeof(data->mac_addr)) == 0)
+						invalid_mac,
+						sizeof(data->mac_addr)) == 0)
 				{
 					IPACMDBG_H("Received invalid Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
 					 data->mac_addr[0], data->mac_addr[1], data->mac_addr[2],
@@ -744,6 +779,8 @@
 					return;
 				}
 
+				handle_header_add_evt(data->mac_addr);
+
 				handle_wan_hdr_init(data->mac_addr);
 				IPACMDBG_H("construct wan header and route rules \n");
 				/* Associate with IP and construct RT-rule */
@@ -1175,13 +1212,15 @@
 	}
 
 	/* Add corresponding ipa_rm_resource_name of TX-endpoint up before IPV6 RT-rule set */
-    IPACM_Iface::ipacmcfg->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false);
+	IPACMDBG_H("dev %s add producer dependency\n", dev_name);
+	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->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false);
 
 	return IPACM_SUCCESS;
 }
 
 /* construct complete ethernet header */
-int IPACM_Wan::handle_header_add_evt(uint8_t mac_addr[6])
+int IPACM_Wan::handle_header_add_evt(uint8_t *mac_addr)
 {
   #define WAN_IFACE_INDEX_LEN 2
 
@@ -1197,10 +1236,10 @@
 					 mac_addr[0], mac_addr[1], mac_addr[2],
 					 mac_addr[3], mac_addr[4], mac_addr[5]);
 
-    if((header_set_v4 == true) || (header_set_v6 == true))
-    {
-	   IPACMDBG_H("Already add STA full header\n");
-       return IPACM_SUCCESS;
+	if((header_set_v4 == true) || (header_set_v6 == true))
+	{
+		IPACMDBG_H("Already add STA full header\n");
+		return IPACM_SUCCESS;
 	}
 	/* add header to IPA */
 	len = sizeof(struct ipa_ioc_add_hdr) + (1 * sizeof(struct ipa_hdr_add));
@@ -1229,6 +1268,15 @@
 		goto fail;
 	}
 
+	if(sCopyHeader.is_eth2_ofst_valid == false)
+	{
+		eth2_ofst_v4 = 0;
+	}
+	else
+	{
+		eth2_ofst_v4 = sCopyHeader.eth2_ofst;
+	}
+
 	IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial);
 	if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE)
 	{
@@ -1244,7 +1292,7 @@
 	}
 
 	/* copy client mac_addr to partial header */
-	memcpy(&pHeaderDescriptor->hdr[0].hdr[IPA_WLAN_PARTIAL_HDR_OFFSET], mac_addr,
+	memcpy(&pHeaderDescriptor->hdr[0].hdr[eth2_ofst_v4], mac_addr,
 					 IPA_MAC_ADDR_SIZE); /* only copy 6 bytes mac-address */
 
 	pHeaderDescriptor->commit = true;
@@ -1306,14 +1354,22 @@
 				           tx_prop->tx[cnt].hdr_name,
 				                   sizeof(sCopyHeader.name));
 
-	IPACMDBG_H("header name: %s from tx: %d\n", sCopyHeader.name,cnt);
-	if (m_header.CopyHeader(&sCopyHeader) == false)
-	{
-		IPACMERR("ioctl copy header failed");
-		res = IPACM_FAILURE;
-		goto fail;
-	}
+			IPACMDBG_H("header name: %s from tx: %d\n", sCopyHeader.name,cnt);
+			if (m_header.CopyHeader(&sCopyHeader) == false)
+			{
+				IPACMERR("ioctl copy header failed");
+				res = IPACM_FAILURE;
+				goto fail;
+			}
 
+			if(sCopyHeader.is_eth2_ofst_valid == false)
+			{
+				eth2_ofst_v6 = 0;
+			}
+			else
+			{
+				eth2_ofst_v6 = sCopyHeader.eth2_ofst;
+			}
                      IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial);
                      if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE)
                      {
@@ -1329,7 +1385,7 @@
                      }
 
 	                 /* copy client mac_addr to partial header */
-	                 memcpy(&pHeaderDescriptor->hdr[0].hdr[IPA_WLAN_PARTIAL_HDR_OFFSET], mac_addr,
+	                 memcpy(&pHeaderDescriptor->hdr[0].hdr[eth2_ofst_v6], mac_addr,
 	                 				 IPA_MAC_ADDR_SIZE); /* only copy 6 bytes mac-address */
 	                 pHeaderDescriptor->commit = true;
 	                 pHeaderDescriptor->num_hdrs = 1;
@@ -2540,26 +2596,7 @@
 	}
 
 	/* ADD corresponding ipa_rm_resource_name of RX-endpoint before adding all IPV4V6 FT-rules */
-	if(rx_prop != NULL)
-	{
-		IPACM_Iface::ipacmcfg->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe],false);
-		IPACMDBG_H(" add producer dependency from %s with registered rx-prop\n", dev_name);
-	}
-	else
-	{
-		/* only wlan may take software-path, not register Rx-property*/
-		if(strcmp(dev_name,dev_wlan0) == 0 || strcmp(dev_name,dev_wlan1) == 0)
-		{
-			IPACM_Iface::ipacmcfg->AddRmDepend(IPA_RM_RESOURCE_HSIC_PROD,true);
-			IPACMDBG_H(" add producer dependency from %s without registered rx-prop \n", dev_name);
-		}
-
-		if(strcmp(dev_name,dev_ecm0) == 0)
-		{
-			IPACM_Iface::ipacmcfg->AddRmDepend(IPA_RM_RESOURCE_USB_PROD,true);
-			IPACMDBG_H(" add producer dependency from %s without registered rx-prop \n", dev_name);
-		}
-	}
+	IPACMDBG_H(" dun add producer dependency from %s with registered rx-prop\n", dev_name);
 
 	if(iptype == IPA_IP_v4)
 	{
@@ -3228,7 +3265,9 @@
 	{
 
 		/* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete IPV4/V6 RT-rule */
-	    IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]);
+		IPACMDBG_H("dev %s add producer dependency\n", dev_name);
+		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]);
 
 		for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
 		{
@@ -3354,6 +3393,8 @@
 	{
 
 		/* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete IPV4/V6 RT-rule */
+		IPACMDBG_H("dev %s add producer dependency\n", dev_name);
+		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]);
 
 		/* Delete the default route*/
@@ -3554,6 +3595,11 @@
 
 	IPACMDBG_H(" wan handle_down_evt \n");
 
+	/* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete IPV4/V6 RT-rule */
+	IPACMDBG_H("dev %s add producer dependency\n", dev_name);
+	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]);
+
 	/* no iface address up, directly close iface*/
 	if (ip_type == IPACM_IP_NULL)
 	{
@@ -3778,6 +3824,8 @@
 	{
 		embms_is_on = false;
 		/* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete IPV4/V6 RT-rule */
+		IPACMDBG_H("dev %s add producer dependency\n", dev_name);
+		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]);
 
 		if (rx_prop != NULL)
@@ -4280,7 +4328,7 @@
 	char index[WAN_IFACE_INDEX_LEN];
 	struct ipa_ioc_copy_hdr sCopyHeader;
 	struct ipa_ioc_add_hdr *pHeaderDescriptor = NULL;
-    uint32_t cnt;
+	uint32_t cnt;
 	int clnt_indx;
 
 	clnt_indx = get_wan_client_index(mac_addr);
@@ -4363,7 +4411,9 @@
 								}
 
 								/* copy client mac_addr to partial header */
-								memcpy(&pHeaderDescriptor->hdr[0].hdr[IPA_WLAN_PARTIAL_HDR_OFFSET], mac_addr, IPA_MAC_ADDR_SIZE); /* only copy 6 bytes mac-address */
+								IPACMDBG_H("header eth2_ofst_valid: %d, eth2_ofst: %d\n",
+										sCopyHeader.is_eth2_ofst_valid, sCopyHeader.eth2_ofst);
+								memcpy(&pHeaderDescriptor->hdr[0].hdr[eth2_ofst_v4], mac_addr, IPA_MAC_ADDR_SIZE); /* only copy 6 bytes mac-address */
 
 								pHeaderDescriptor->commit = true;
 								pHeaderDescriptor->num_hdrs = 1;
@@ -4450,7 +4500,7 @@
 				}
 
 				/* copy client mac_addr to partial header */
-				memcpy(&pHeaderDescriptor->hdr[0].hdr[IPA_WLAN_PARTIAL_HDR_OFFSET], mac_addr, IPA_MAC_ADDR_SIZE); /* only copy 6 bytes mac-address */
+				memcpy(&pHeaderDescriptor->hdr[0].hdr[eth2_ofst_v6], mac_addr, IPA_MAC_ADDR_SIZE); /* only copy 6 bytes mac-address */
 
 				pHeaderDescriptor->commit = true;
 				pHeaderDescriptor->num_hdrs = 1;
@@ -4601,7 +4651,6 @@
 			      {
 			  	    IPACMDBG_H("Already see this ipv6 addr for client:%d\n", clnt_indx);
 			  	    return IPACM_FAILURE; /* not setup the RT rules*/
-			  		break;
 			      }
 		       }
 
@@ -4668,8 +4717,10 @@
 					))
 	{
 
-        /* Add corresponding ipa_rm_resource_name of TX-endpoint up before IPV6 RT-rule set */
-        IPACM_Iface::ipacmcfg->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false);
+        	/* Add corresponding ipa_rm_resource_name of TX-endpoint up before IPV6 RT-rule set */
+		IPACMDBG_H("dev %s add producer dependency\n", dev_name);
+		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->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false);
 
 		rt_rule = (struct ipa_ioc_add_rt_rule *)
 			 calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
diff --git a/ipacm/src/IPACM_Wlan.cpp b/ipacm/src/IPACM_Wlan.cpp
index ae00315..cb6fb2a 100644
--- a/ipacm/src/IPACM_Wlan.cpp
+++ b/ipacm/src/IPACM_Wlan.cpp
@@ -584,7 +584,9 @@
     /* ADD corresponding ipa_rm_resource_name of RX-endpoint before adding all IPV4V6 FT-rules */
 	if(rx_prop != NULL)
 	{
-	    IPACM_Iface::ipacmcfg->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe],false);
+		IPACMDBG_H("dev %s add producer dependency\n", dev_name);
+		IPACMDBG_H("depend Got pipe %d rm index : %d \n", rx_prop->rx[0].src_pipe, IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe]);
+		IPACM_Iface::ipacmcfg->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe],false);
 		IPACMDBG_H("Add producer dependency from %s with registered rx-prop\n", dev_name);
 	}
 	else
@@ -2088,7 +2090,9 @@
 	/* Delete corresponding ipa_rm_resource_name of RX-endpoint after delete all IPV4V6 FT-rule */
 	if (rx_prop != NULL)
 	{
-	IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe]);
+		IPACMDBG_H("dev %s add producer dependency\n", dev_name);
+		IPACMDBG_H("depend Got pipe %d rm index : %d \n", rx_prop->rx[0].src_pipe, IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe]);
+		IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe]);
 		free(rx_prop);
 	}