Merge "IPACM : Add support for the XLAT feature"
diff --git a/ipacm/inc/IPACM_Defs.h b/ipacm/inc/IPACM_Defs.h
index 37f3ff4..e47f590 100644
--- a/ipacm/inc/IPACM_Defs.h
+++ b/ipacm/inc/IPACM_Defs.h
@@ -154,16 +154,16 @@
 	IPA_HANDLE_WLAN_UP,                       /* 24 ipacm_event_iface_up */
 	IPA_HANDLE_LAN_UP,                        /* 25 ipacm_event_iface_up */
 	IPA_WLAN_CLIENT_ADD_EVENT_EX,             /* 26 ipacm_event_data_wlan_ex */
-	IPA_HANDLE_WAN_UP_V6,					  /* 27 NULL */
-	IPA_HANDLE_WAN_DOWN_V6,					  /* 28 NULL */
-	IPA_LAN_CLIENT_ACTIVE,					  /* 29 ipacm_event_lan_client*/
-	IPA_LAN_CLIENT_INACTIVE,				  /* 30 ipacm_event_lan_client*/
-	IPA_LAN_CLIENT_DISCONNECT,				  /* 31 ipacm_event_lan_client*/
-	IPA_LAN_CLIENT_POWER_SAVE,				  /* 32 ipacm_event_lan_client*/
-	IPA_LAN_CLIENT_POWER_RECOVER,			  /* 33 ipacm_event_lan_client*/
-	IPA_LAN_TO_LAN_NEW_CONNECTION,			  /* 34 ipacm_event_connection */
-	IPA_LAN_TO_LAN_DEL_CONNECTION,			  /* 35 ipacm_event_connection */
-	IPA_LAN_DELETE_SELF,					  /* 36 ipacm_event_data_fid */
+	IPA_HANDLE_WAN_UP_V6,                     /* 27 NULL */
+	IPA_HANDLE_WAN_DOWN_V6,                   /* 28 NULL */
+	IPA_LAN_CLIENT_ACTIVE,                    /* 29 ipacm_event_lan_client*/
+	IPA_LAN_CLIENT_INACTIVE,                  /* 30 ipacm_event_lan_client*/
+	IPA_LAN_CLIENT_DISCONNECT,                /* 31 ipacm_event_lan_client*/
+	IPA_LAN_CLIENT_POWER_SAVE,                /* 32 ipacm_event_lan_client*/
+	IPA_LAN_CLIENT_POWER_RECOVER,             /* 33 ipacm_event_lan_client*/
+	IPA_LAN_TO_LAN_NEW_CONNECTION,            /* 34 ipacm_event_connection */
+	IPA_LAN_TO_LAN_DEL_CONNECTION,            /* 35 ipacm_event_connection */
+	IPA_LAN_DELETE_SELF,                      /* 36 ipacm_event_data_fid */
 	IPA_WLAN_LINK_DOWN_EVENT,                 /* 37 ipacm_event_data_mac */
 	IPA_USB_LINK_UP_EVENT,                    /* 38 ipacm_event_data_fid */
 	IPA_PROCESS_CT_MESSAGE_V6,                /* 39 ipacm_ct_evt_data */
@@ -179,7 +179,8 @@
 	IPA_ETH_BRIDGE_HDR_PROC_CTX_UNSET_EVENT,  /* 49 ipacm_event_data_fid */
 	IPA_WLAN_SWITCH_TO_SCC,                   /* 50 No Data */
 	IPA_WLAN_SWITCH_TO_MCC,                   /* 51 No Data */
-	IPA_CRADLE_WAN_MODE_SWITCH,				  /* 52 ipacm_event_cradle_wan_mode */
+	IPA_CRADLE_WAN_MODE_SWITCH,               /* 52 ipacm_event_cradle_wan_mode */
+	IPA_WAN_XLAT_CONNECT_EVENT,               /* 53 ipacm_event_data_fid */
 	IPACM_EVENT_MAX
 } ipa_cm_event_id;
 
@@ -305,6 +306,7 @@
 	uint32_t addr_mask;
 	uint32_t ipv6_prefix[2];
 	bool is_sta;
+	uint8_t xlat_mux_id;
 }ipacm_event_iface_up;
 
 typedef enum
diff --git a/ipacm/inc/IPACM_Lan.h b/ipacm/inc/IPACM_Lan.h
index e520d58..42fd29b 100644
--- a/ipacm/inc/IPACM_Lan.h
+++ b/ipacm/inc/IPACM_Lan.h
@@ -146,13 +146,12 @@
 	uint32_t private_fl_rule_hdl[IPA_MAX_PRIVATE_SUBNET_ENTRIES];
 
 	/* LAN-iface's callback function */
-	void event_callback(ipa_cm_event_id event,
-											void *data);
+	void event_callback(ipa_cm_event_id event, void *data);
 
 	virtual int handle_wan_up(ipa_ip_type ip_type);
 
 	/* configure filter rule for wan_up event*/
-	virtual int handle_wan_up_ex(ipacm_ext_prop* ext_prop, ipa_ip_type iptype);
+	virtual int handle_wan_up_ex(ipacm_ext_prop* ext_prop, ipa_ip_type iptype, uint8_t xlat_mux_id);
 
 	/* delete filter rule for wan_down event*/
 	virtual int handle_wan_down(bool is_sta_mode);
@@ -171,7 +170,7 @@
 	static bool odu_up;
 
 	/* install UL filter rule from Q6 */
-	virtual int handle_uplink_filter_rule(ipacm_ext_prop* prop, ipa_ip_type iptype);
+	virtual int handle_uplink_filter_rule(ipacm_ext_prop* prop, ipa_ip_type iptype, uint8_t xlat_mux_id);
 
 	int add_lan2lan_flt_rule(ipa_ip_type iptype, uint32_t src_v4_addr, uint32_t dst_v4_addr, uint32_t* src_v6_addr, uint32_t* dst_v6_addr, uint32_t* rule_hdl);
 
@@ -327,7 +326,7 @@
 
 	NatApp *Nat_App;
 
-    int ipv6_set;
+	int ipv6_set;
 
 	uint32_t ODU_hdr_hdl_v4, ODU_hdr_hdl_v6;
 
diff --git a/ipacm/inc/IPACM_Wan.h b/ipacm/inc/IPACM_Wan.h
index 5160ac3..9009136 100644
--- a/ipacm/inc/IPACM_Wan.h
+++ b/ipacm/inc/IPACM_Wan.h
@@ -86,6 +86,7 @@
 
 	static bool wan_up;
 	static bool wan_up_v6;
+	static uint8_t xlat_mux_id;
 
 	IPACM_Wan(int, ipacm_wan_iface_type, uint8_t *);
 	virtual ~IPACM_Wan();
@@ -100,6 +101,10 @@
 		return wan_up_v6;
 	}
 
+	static bool getXlat_Mux_Id()
+	{
+		return xlat_mux_id;
+	}
 
 	void event_callback(ipa_cm_event_id event,
 											void *data);
@@ -168,6 +173,8 @@
 	int header_name_count;
 	int num_wan_client;
 	uint8_t invalid_mac[IPA_MAC_ADDR_SIZE];
+	bool is_xlat;
+
 
 	inline ipa_wan_client* get_client_memptr(ipa_wan_client *param, int cnt)
 	{
diff --git a/ipacm/inc/IPACM_Wlan.h b/ipacm/inc/IPACM_Wlan.h
index fb5555a..d49215f 100644
--- a/ipacm/inc/IPACM_Wlan.h
+++ b/ipacm/inc/IPACM_Wlan.h
@@ -313,7 +313,7 @@
 	virtual int handle_private_subnet(ipa_ip_type iptype);
 
 	/* install UL filter rule from Q6 */
-	virtual int handle_uplink_filter_rule(ipacm_ext_prop* prop, ipa_ip_type iptype);
+	virtual int handle_uplink_filter_rule(ipacm_ext_prop* prop, ipa_ip_type iptype, uint8_t xlat_mux_id);
 
 	/* install TCP control filter rules */
 	virtual void install_tcp_ctl_flt_rule(ipa_ip_type iptype);
diff --git a/ipacm/src/IPACM_IfaceManager.cpp b/ipacm/src/IPACM_IfaceManager.cpp
index 4e6c438..c3bc6bd 100644
--- a/ipacm/src/IPACM_IfaceManager.cpp
+++ b/ipacm/src/IPACM_IfaceManager.cpp
@@ -362,6 +362,7 @@
 					IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, w);
 					IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, w);
 					IPACM_EvtDispatcher::registr(IPA_CFG_CHANGE_EVENT, w); 		// register for IPA_CFG_CHANGE event
+					IPACM_EvtDispatcher::registr(IPA_WAN_XLAT_CONNECT_EVENT, w);
 					if(is_sta_mode == WLAN_WAN)
 					{
 						IPACM_EvtDispatcher::registr(IPA_WLAN_LINK_DOWN_EVENT, w); // for STA mode
diff --git a/ipacm/src/IPACM_Lan.cpp b/ipacm/src/IPACM_Lan.cpp
index 624f548..3d7f712 100644
--- a/ipacm/src/IPACM_Lan.cpp
+++ b/ipacm/src/IPACM_Lan.cpp
@@ -93,19 +93,18 @@
 	/* support eth multiple clients */
 	if(iface_query != NULL)
 	{
-
-	if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat != WLAN_IF)
-	{
-		eth_client_len = (sizeof(ipa_eth_client)) + (iface_query->num_tx_props * sizeof(eth_client_rt_hdl));
-		eth_client = (ipa_eth_client *)calloc(IPA_MAX_NUM_ETH_CLIENTS, eth_client_len);
-		if (eth_client == NULL)
+		if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat != WLAN_IF)
 		{
-			IPACMERR("unable to allocate memory\n");
-			return;
+			eth_client_len = (sizeof(ipa_eth_client)) + (iface_query->num_tx_props * sizeof(eth_client_rt_hdl));
+			eth_client = (ipa_eth_client *)calloc(IPA_MAX_NUM_ETH_CLIENTS, eth_client_len);
+			if (eth_client == NULL)
+			{
+				IPACMERR("unable to allocate memory\n");
+				return;
+			}
 		}
-	}
 
-	IPACMDBG_H(" IPACM->IPACM_Lan(%d) constructor: Tx:%d Rx:%d\n", ipa_if_num,
+		IPACMDBG_H(" IPACM->IPACM_Lan(%d) constructor: Tx:%d Rx:%d\n", ipa_if_num,
 					 iface_query->num_tx_props, iface_query->num_rx_props);
 #ifdef FEATURE_ETH_BRIDGE_LE
 		if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == LAN_IF && tx_prop != NULL)
@@ -444,7 +443,8 @@
 							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);
+									handle_wan_up_ex(ext_prop, IPA_IP_v4,
+												IPACM_Wan::getXlat_Mux_Id());
 								}
 							else
 							{
@@ -461,7 +461,7 @@
 							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);
+									handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
 								}
 							else
 							{
@@ -529,8 +529,8 @@
 		if(data_wan->is_sta == false)
 		{
 				ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
-				handle_wan_up_ex(ext_prop, IPA_IP_v4);
-			}
+				handle_wan_up_ex(ext_prop, IPA_IP_v4, data_wan->xlat_mux_id);
+		}
 		else
 		{
 			handle_wan_up(IPA_IP_v4);
@@ -554,7 +554,7 @@
 		if(data_wan->is_sta == false)
 		{
 				ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
-				handle_wan_up_ex(ext_prop, IPA_IP_v6);
+				handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
 			}
 		else
 		{
@@ -1308,7 +1308,7 @@
 	return IPACM_SUCCESS;
 }
 
-int IPACM_Lan::handle_wan_up_ex(ipacm_ext_prop* ext_prop, ipa_ip_type iptype)
+int IPACM_Lan::handle_wan_up_ex(ipacm_ext_prop *ext_prop, ipa_ip_type iptype, uint8_t xlat_mux_id)
 {
 	int fd, ret = IPACM_SUCCESS, cnt;
 	IPACM_Config* ipacm_config = IPACM_Iface::ipacmcfg;
@@ -1343,8 +1343,8 @@
 	if ((num_dft_rt_v6 ==1 && iptype ==IPA_IP_v6) ||
 			(iptype ==IPA_IP_v4))
 	{
-		IPACMDBG_H("num_dft_rt_v6 %d iptype %d\n", num_dft_rt_v6, iptype);
-		ret = handle_uplink_filter_rule(ext_prop, iptype);
+		IPACMDBG_H("num_dft_rt_v6 %d iptype %d xlat_mux_id: %d \n", num_dft_rt_v6, iptype, xlat_mux_id);
+		ret = handle_uplink_filter_rule(ext_prop, iptype, xlat_mux_id);
 	}
 	return ret;
 }
@@ -2717,7 +2717,7 @@
 }
 
 /* install UL filter rule from Q6 */
-int IPACM_Lan::handle_uplink_filter_rule(ipacm_ext_prop* prop, ipa_ip_type iptype)
+int IPACM_Lan::handle_uplink_filter_rule(ipacm_ext_prop *prop, ipa_ip_type iptype, uint8_t xlat_mux_id)
 {
 	ipa_flt_rule_add flt_rule_entry;
 	int len = 0, cnt, ret = IPACM_SUCCESS;
@@ -2725,6 +2725,7 @@
 	ipa_fltr_installed_notif_req_msg_v01 flt_index;
 	int fd;
 	int i, index;
+	uint32_t value = 0;
 
 	IPACMDBG_H("Set extended property rules in LAN\n");
 
@@ -2822,6 +2823,19 @@
 					 &prop->prop[cnt].eq_attrib,
 					 sizeof(prop->prop[cnt].eq_attrib));
 		flt_rule_entry.rule.rt_tbl_idx = prop->prop[cnt].rt_tbl_idx;
+
+		/* Handle XLAT configuration */
+		if ((iptype == IPA_IP_v4) && prop->prop[cnt].is_xlat_rule && (xlat_mux_id != 0))
+		{
+			/* fill the value of meta-data */
+			value = xlat_mux_id;
+			flt_rule_entry.rule.eq_attrib.metadata_meq32_present = 1;
+			flt_rule_entry.rule.eq_attrib.metadata_meq32.offset = 0;
+			flt_rule_entry.rule.eq_attrib.metadata_meq32.value = (value & 0xFF) << 16;
+			flt_rule_entry.rule.eq_attrib.metadata_meq32.mask = 0x00FF0000;
+			IPACMDBG_H("xlat meta-data is modified fur rult: %d has index %d with xlat_mux_id: %d\n",
+					cnt, index, xlat_mux_id);
+		}
 		memcpy(&pFilteringTable->rules[cnt], &flt_rule_entry, sizeof(flt_rule_entry));
 
 		IPACMDBG_H("Modem UL filtering rule %d has index %d\n", cnt, index);
diff --git a/ipacm/src/IPACM_Main.cpp b/ipacm/src/IPACM_Main.cpp
index 199caf8..1e3cce7 100644
--- a/ipacm/src/IPACM_Main.cpp
+++ b/ipacm/src/IPACM_Main.cpp
@@ -112,13 +112,14 @@
 	__stringify(IPA_LAN_CLIENT_POWER_RECOVER),			   /* 33 ipacm_event_lan_client*/
 	__stringify(IPA_LAN_TO_LAN_NEW_CONNECTION),			   /* 34 ipacm_event_connection */
 	__stringify(IPA_LAN_TO_LAN_DEL_CONNECTION),			   /* 35 ipacm_event_connection */
-	__stringify(IPA_LAN_DELETE_SELF),		               /* 36 ipacm_event_data_fid */
-	__stringify(IPA_WLAN_LINK_DOWN_EVENT),                 /* 37 ipacm_event_data_mac */
-	__stringify(IPA_USB_LINK_UP_EVENT),                    /* 38 ipacm_event_data_fid */
-    __stringify(IPA_PROCESS_CT_MESSAGE_V6),			       /* 39 ipacm_ct_evt_data */
+	__stringify(IPA_LAN_DELETE_SELF),                          /* 36 ipacm_event_data_fid */
+	__stringify(IPA_WLAN_LINK_DOWN_EVENT),                     /* 37 ipacm_event_data_mac */
+	__stringify(IPA_USB_LINK_UP_EVENT),                        /* 38 ipacm_event_data_fid */
+	__stringify(IPA_PROCESS_CT_MESSAGE_V6),                    /* 39 ipacm_ct_evt_data */
 	__stringify(IPA_PRIVATE_SUBNET_CHANGE_EVENT),		   /* 40 ipacm_event_data_fid */
 	__stringify(IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT),		   /* 41 ipacm_event_data_fid */
 	__stringify(IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT),		   /* 42 ipacm_event_data_fid */
+	__stringify(IPA_WAN_XLAT_CONNECT_EVENT),                   /* 43 ipacm_event_data_fid */
 };
 
 #define IPA_DRIVER  "/dev/ipa"
@@ -252,8 +253,8 @@
 }
 
 
-/* start IPACM WLAN-driver notifier */
-void* ipa_driver_wlan_notifier(void *param)
+/* start IPACM wan-driver notifier */
+void* ipa_driver_msg_notifier(void *param)
 {
 	int length, fd, cnt;
 	char buffer[IPA_DRIVER_WLAN_BUF_LEN];
@@ -266,7 +267,7 @@
 
 	ipacm_cmd_q_data evt_data;
 	ipacm_event_data_mac *data = NULL;
-    ipacm_event_data_fid *data_fid = NULL;
+	ipacm_event_data_fid *data_fid = NULL;
 	ipacm_event_data_iptype *data_iptype = NULL;
 	ipacm_event_data_wlan_ex *data_ex;
 
@@ -537,7 +538,7 @@
 		case ECM_CONNECT:
 			memcpy(&event_ecm, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_ecm_msg));
 			IPACMDBG_H("Received ECM_CONNECT name: %s\n",event_ecm.name);
-            data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
+			data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
 			if(data_fid == NULL)
 			{
 				IPACMERR("unable to allocate memory for event_ecm data_fid\n");
@@ -565,7 +566,7 @@
 		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);
-            data_iptype = (ipacm_event_data_iptype *)malloc(sizeof(ipacm_event_data_iptype));
+			data_iptype = (ipacm_event_data_iptype *)malloc(sizeof(ipacm_event_data_iptype));
 			if(data_iptype == NULL)
 			{
 				IPACMERR("unable to allocate memory for event_ecm data_iptype\n");
@@ -580,7 +581,7 @@
 		case WAN_UPSTREAM_ROUTE_DEL:
 			memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_wan_msg));
 			IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_DEL name: %s, tethered name: %s\n", event_wan.upstream_ifname, event_wan.tethered_ifname);
-            data_iptype = (ipacm_event_data_iptype *)malloc(sizeof(ipacm_event_data_iptype));
+			data_iptype = (ipacm_event_data_iptype *)malloc(sizeof(ipacm_event_data_iptype));
 			if(data_iptype == NULL)
 			{
 				IPACMERR("unable to allocate memory for event_ecm data_iptype\n");
@@ -631,12 +632,46 @@
 				break;
 			}
 			continue;
+
+		case WAN_XLAT_CONNECT:
+			memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta),
+				sizeof(struct ipa_wan_msg));
+			IPACMDBG_H("Received WAN_XLAT_CONNECT name: %s\n",
+					event_wan.upstream_ifname);
+
+			/* post IPA_LINK_UP_EVENT event
+			 * may be WAN interface is not up
+			*/
+			data_fid = (ipacm_event_data_fid *)calloc(1, sizeof(ipacm_event_data_fid));
+			if(data_fid == NULL)
+			{
+				IPACMERR("unable to allocate memory for xlat event\n");
+				return NULL;
+			}
+			ipa_get_if_index(event_wan.upstream_ifname, &(data_fid->if_index));
+			evt_data.event = IPA_LINK_UP_EVENT;
+			evt_data.evt_data = data_fid;
+			IPACMDBG_H("Posting IPA_LINK_UP_EVENT event:%d\n", evt_data.event);
+			IPACM_EvtDispatcher::PostEvt(&evt_data);
+
+			/* post IPA_WAN_XLAT_CONNECT_EVENT event */
+			memset(&evt_data, 0, sizeof(evt_data));
+			data_fid = (ipacm_event_data_fid *)calloc(1, sizeof(ipacm_event_data_fid));
+			if(data_fid == NULL)
+			{
+				IPACMERR("unable to allocate memory for xlat event\n");
+				return NULL;
+			}
+			ipa_get_if_index(event_wan.upstream_ifname, &(data_fid->if_index));
+			evt_data.event = IPA_WAN_XLAT_CONNECT_EVENT;
+			evt_data.evt_data = data_fid;
+			IPACMDBG_H("Posting IPA_WAN_XLAT_CONNECT_EVENT event:%d\n", evt_data.event);
+			break;
 		default:
 			IPACMDBG_H("Unhandled message type: %d\n", event_hdr.msg_type);
 			continue;
 
 		}
-
 		/* finish command queue */
 		IPACMDBG_H("Posting event:%d\n", evt_data.event);
 		IPACM_EvtDispatcher::PostEvt(&evt_data);
@@ -762,7 +797,7 @@
 
 	if (IPACM_SUCCESS == ipa_driver_thread)
 	{
-		ret = pthread_create(&ipa_driver_thread, NULL, ipa_driver_wlan_notifier, NULL);
+		ret = pthread_create(&ipa_driver_thread, NULL, ipa_driver_msg_notifier, NULL);
 		if (IPACM_SUCCESS != ret)
 		{
 			IPACMERR("unable to create ipa_driver_wlan thread\n");
diff --git a/ipacm/src/IPACM_Wan.cpp b/ipacm/src/IPACM_Wan.cpp
index 785d8e2..12bfeba 100644
--- a/ipacm/src/IPACM_Wan.cpp
+++ b/ipacm/src/IPACM_Wan.cpp
@@ -52,6 +52,7 @@
 
 bool IPACM_Wan::wan_up = false;
 bool IPACM_Wan::wan_up_v6 = false;
+uint8_t IPACM_Wan::xlat_mux_id = 0;
 
 int IPACM_Wan::num_v4_flt_rule = 0;
 int IPACM_Wan::num_v6_flt_rule = 0;
@@ -71,8 +72,8 @@
 uint32_t IPACM_Wan::backhaul_ipv6_prefix[2];
 
 IPACM_Wan::IPACM_Wan(int iface_index,
-       ipacm_wan_iface_type is_sta_mode,
-       uint8_t *mac_addr) : IPACM_Iface(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;
@@ -108,6 +109,9 @@
 	num_wan_client = 0;
 	header_name_count = 0;
 	memset(invalid_mac, 0, sizeof(invalid_mac));
+
+	is_xlat = false;
+
 	if(iface_query != NULL)
 	{
 		wan_client_len = (sizeof(ipa_wan_client)) + (iface_query->num_tx_props * sizeof(wan_client_rt_hdl));
@@ -502,6 +506,19 @@
 		}
 		break;
 
+	case IPA_WAN_XLAT_CONNECT_EVENT:
+		{
+			IPACMDBG_H("Recieved IPA_WAN_XLAT_CONNECT_EVENT\n");
+			ipacm_event_data_fid *data = (ipacm_event_data_fid *)param;
+			ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data->if_index);
+			if ((ipa_interface_index == ipa_if_num) && (m_is_sta_mode == Q6_WAN))
+			{
+				is_xlat = true;
+				IPACMDBG_H("WAN-LTE (%s) link up, iface: %d is_xlat: \n",
+						IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,data->if_index, is_xlat);
+			}
+			break;
+		}
 	case IPA_CFG_CHANGE_EVENT:
 		{
 			if ( (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ipa_if_cate) &&
@@ -785,15 +802,21 @@
 					/* Check & construct STA header */
 					handle_sta_header_add_evt();
 					handle_route_add_evt(data->iptype);
+					/* Add IPv6 routing table if XLAT is enabled */
+					if(is_xlat && (m_is_sta_mode == Q6_WAN) && (active_v6 == false))
+					{
+						IPACMDBG_H("XLAT enabled: adding IPv6 routing table dev (%s)\n", dev_name);
+						handle_route_add_evt(IPA_IP_v6);
+					}
 				}
 				else if ((data->iptype == IPA_IP_v6) &&
-								 (!data->ipv6_addr[0]) && (!data->ipv6_addr[1]) && (!data->ipv6_addr[2]) && (!data->ipv6_addr[3]) && (active_v6 == false)
-								 && (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX))
+						(!data->ipv6_addr[0]) && (!data->ipv6_addr[1]) && (!data->ipv6_addr[2]) && (!data->ipv6_addr[3]) &&
+						(active_v6 == false) &&	(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX))
 				{
 					IPACMDBG_H("\n get default v6 route (dst:00.00.00.00)\n");
 					IPACMDBG_H(" IPV6 value: %08x:%08x:%08x:%08x \n",
-									 data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]);
-				handle_route_add_evt(data->iptype);
+							data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]);
+					handle_route_add_evt(data->iptype);
 				}
 			}
 			else /* double check if current default iface is not itself */
@@ -1375,8 +1398,24 @@
 		}
 		IPACMDBG_H("Posting IPA_HANDLE_WAN_UP with below information:\n");
 		IPACMDBG_H("if_name:%s, ipv4_address:0x%x, is sta mode:%d\n",
-			wanup_data->ifname, wanup_data->ipv4_addr,  wanup_data->is_sta);
+				wanup_data->ifname, wanup_data->ipv4_addr, wanup_data->is_sta);
 		memset(&evt_data, 0, sizeof(evt_data));
+
+		/* send xlat configuration for installing uplink rules */
+		if(is_xlat && (m_is_sta_mode == Q6_WAN))
+		{
+			IPACM_Wan::xlat_mux_id = ext_prop->ext[0].mux_id;
+			wanup_data->xlat_mux_id = IPACM_Wan::xlat_mux_id;
+			IPACMDBG_H("Set xlat configuraiton with below information:\n");
+			IPACMDBG_H("xlat_enabled:  xlat_mux_id: %d \n",
+					is_xlat, xlat_mux_id);
+		}
+		else
+		{
+			IPACM_Wan::xlat_mux_id = 0;
+			wanup_data->xlat_mux_id = 0;
+			IPACMDBG_H("No xlat configuratio:\n");
+		}
 		evt_data.event = IPA_HANDLE_WAN_UP;
 		evt_data.evt_data = (void *)wanup_data;
 		IPACM_EvtDispatcher::PostEvt(&evt_data);
@@ -3003,12 +3042,14 @@
 			return ret;
 		}
 
-		IPACMDBG_H("Wan interface has %d tx props, %d rx props and %d ext props\n", iface_query->num_tx_props, iface_query->num_rx_props, iface_query->num_ext_props);
+		IPACMDBG_H("Wan interface has %d tx props, %d rx props and %d ext props\n",
+				iface_query->num_tx_props, iface_query->num_rx_props, iface_query->num_ext_props);
 
 		for (cnt = 0; cnt < ext_prop->num_ext_props; cnt++)
 		{
-			IPACMDBG_H("Ex(%d): ip-type: %d, mux_id: %d, flt_action: %d\n, rt_tbl_idx: %d, flt_hdr: %d \n",
-							 cnt, ext_prop->ext[cnt].ip, ext_prop->ext[cnt].mux_id, ext_prop->ext[cnt].action, ext_prop->ext[cnt].rt_tbl_idx, ext_prop->ext[cnt].filter_hdl);
+			IPACMDBG_H("Ex(%d): ip-type: %d, mux_id: %d, flt_action: %d\n, rt_tbl_idx: %d, flt_hdr: %d  is_xlat_rule: %d\n",
+					cnt, ext_prop->ext[cnt].ip, ext_prop->ext[cnt].mux_id, ext_prop->ext[cnt].action,
+					ext_prop->ext[cnt].rt_tbl_idx, ext_prop->ext[cnt].filter_hdl, ext_prop->ext[cnt].is_xlat_rule);
 		}
 
 		if(IPACM_Wan::is_ext_prop_set == false)
diff --git a/ipacm/src/IPACM_Wlan.cpp b/ipacm/src/IPACM_Wlan.cpp
index f75b806..909a044 100644
--- a/ipacm/src/IPACM_Wlan.cpp
+++ b/ipacm/src/IPACM_Wlan.cpp
@@ -346,7 +346,8 @@
 							if(IPACM_Wan::backhaul_is_sta_mode == false)
 							{
 								ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
-								IPACM_Lan::handle_wan_up_ex(ext_prop, IPA_IP_v4);
+								IPACM_Lan::handle_wan_up_ex(ext_prop, IPA_IP_v4,
+												IPACM_Wan::getXlat_Mux_Id());
 							}
 							else
 							{
@@ -366,7 +367,7 @@
 							if(IPACM_Wan::backhaul_is_sta_mode == false)
 							{
 								ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
-								IPACM_Lan::handle_wan_up_ex(ext_prop, IPA_IP_v6);
+								IPACM_Lan::handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
 							}
 							else
 							{
@@ -389,7 +390,6 @@
 		break;
 
 	case IPA_HANDLE_WAN_UP:
-	{
 		IPACMDBG_H("Received IPA_HANDLE_WAN_UP event\n");
 
 		data_wan = (ipacm_event_iface_up*)param;
@@ -401,17 +401,16 @@
 		IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta);
 		if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
 		{
-		if(data_wan->is_sta == false)
-		{
+			if(data_wan->is_sta == false)
+			{
 				ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
-				IPACM_Lan::handle_wan_up_ex(ext_prop, IPA_IP_v4);
+				IPACM_Lan::handle_wan_up_ex(ext_prop, IPA_IP_v4, data_wan->xlat_mux_id);
 			}
-		else
-		{
-			IPACM_Lan::handle_wan_up(IPA_IP_v4);
+			else
+			{
+				IPACM_Lan::handle_wan_up(IPA_IP_v4);
+			}
 		}
-	}
-	}
 		break;
 
 	case IPA_HANDLE_WAN_UP_V6:
@@ -436,7 +435,7 @@
 			if(data_wan->is_sta == false)
 			{
 				ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
-				IPACM_Lan::handle_wan_up_ex(ext_prop, IPA_IP_v6);
+				IPACM_Lan::handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
 			}
 			else
 			{
@@ -1252,16 +1251,16 @@
 }
 
 /* install UL filter rule from Q6 */
-int IPACM_Wlan::handle_uplink_filter_rule(ipacm_ext_prop* prop, ipa_ip_type iptype)
+int IPACM_Wlan::handle_uplink_filter_rule(ipacm_ext_prop *prop, ipa_ip_type iptype, uint8_t xlat_mux_id)
 {
 	ipa_flt_rule_add flt_rule_entry;
 	int len = 0, cnt, ret = IPACM_SUCCESS, index;
 	ipa_ioc_add_flt_rule *pFilteringTable;
 	ipa_fltr_installed_notif_req_msg_v01 flt_index;
-	int fd;
-	int i;
+	int fd, i;
+	uint32_t value = 0;
 
-	IPACMDBG_H("Set extended property rules in LAN\n");
+	IPACMDBG_H("Set extended property rules in WLAN\n");
 
 	if (rx_prop == NULL)
 	{
@@ -1364,6 +1363,20 @@
 					 &prop->prop[cnt].eq_attrib,
 					 sizeof(prop->prop[cnt].eq_attrib));
 		flt_rule_entry.rule.rt_tbl_idx = prop->prop[cnt].rt_tbl_idx;
+
+		/* Handle XLAT configuration */
+		if ((iptype == IPA_IP_v4) && prop->prop[cnt].is_xlat_rule && (xlat_mux_id != 0))
+		{
+			/* fill the value of meta-data */
+			value = xlat_mux_id;
+			flt_rule_entry.rule.eq_attrib.metadata_meq32_present = 1;
+			flt_rule_entry.rule.eq_attrib.metadata_meq32.offset = 0;
+			flt_rule_entry.rule.eq_attrib.metadata_meq32.value = (value & 0xFF) << 16;
+			flt_rule_entry.rule.eq_attrib.metadata_meq32.mask = 0x00FF0000;
+			IPACMDBG_H("xlat meta-data is modified for rule: %d has index: %d with xlat_mux_id: %d\n",
+					cnt, index, xlat_mux_id);
+                }
+
 		memcpy(&pFilteringTable->rules[cnt], &flt_rule_entry, sizeof(flt_rule_entry));
 
 		IPACMDBG_H("Modem UL filtering rule %d has index %d\n", cnt, index);