Merge "IPACM: Add error check while querying TX and RX properties"
diff --git a/ipacm/inc/IPACM_Lan.h b/ipacm/inc/IPACM_Lan.h
index 65a5372..386b050 100644
--- a/ipacm/inc/IPACM_Lan.h
+++ b/ipacm/inc/IPACM_Lan.h
@@ -74,6 +74,12 @@
 	SRC_LAN
 } eth_bridge_src_iface;
 
+typedef enum
+{
+	DST_WLAN,
+	DST_LAN
+} eth_bridge_dst_iface;
+
 /* Support multiple eth client */
 typedef struct _eth_client_rt_hdl
 {
diff --git a/ipacm/inc/IPACM_Wan.h b/ipacm/inc/IPACM_Wan.h
index 127b195..0b839f0 100644
--- a/ipacm/inc/IPACM_Wan.h
+++ b/ipacm/inc/IPACM_Wan.h
@@ -121,7 +121,12 @@
 	static uint32_t backhaul_ipv6_prefix[2];
 
 	static bool embms_is_on;
-	static bool cradle_backhaul_is_wan_bridge;
+	static bool backhaul_is_wan_bridge;
+
+	static bool isWan_Bridge_Mode()
+	{
+		return backhaul_is_wan_bridge;
+	}
 
 private:
 
diff --git a/ipacm/inc/IPACM_Wlan.h b/ipacm/inc/IPACM_Wlan.h
index f2fc5ef..598c14f 100644
--- a/ipacm/inc/IPACM_Wlan.h
+++ b/ipacm/inc/IPACM_Wlan.h
@@ -318,6 +318,8 @@
 
 	void eth_bridge_handle_wlan_SCC_MCC_switch(ipa_ip_type iptype);
 
+	int eth_bridge_modify_wlan_client_flt_rule(uint8_t* mac, eth_bridge_dst_iface dst_iface, ipa_ip_type iptype);
+
 	int eth_bridge_modify_wlan_rt_rule(uint8_t* mac, eth_bridge_src_iface src_iface, ipa_ip_type iptyp);
 
 	/*handle wlan access mode switch */
diff --git a/ipacm/src/IPACM_IfaceManager.cpp b/ipacm/src/IPACM_IfaceManager.cpp
index 3cc0751..0f6424c 100644
--- a/ipacm/src/IPACM_IfaceManager.cpp
+++ b/ipacm/src/IPACM_IfaceManager.cpp
@@ -78,7 +78,7 @@
 				IPACM_Iface::ipacmcfg->Init();
 			break;
 		case IPA_LINK_UP_EVENT:
-			IPACMDBG_H("link up %d: \n", evt_data->if_index);
+			IPACMDBG_H("Recieved IPA_LINK_UP_EVENT event: link up %d: \n", evt_data->if_index);
 			ipa_interface_index = IPACM_Iface::iface_ipa_index_query(evt_data->if_index);
 			/* LTE-backhaul */
 			if(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat == EMBMS_IF)
@@ -95,6 +95,7 @@
 			break;
 
 		case IPA_USB_LINK_UP_EVENT:
+			IPACMDBG_H("Recieved IPA_USB_LINK_UP_EVENT event: link up %d: \n", evt_data->if_index);
 			ipa_interface_index = IPACM_Iface::iface_ipa_index_query(evt_data->if_index);
 			/* check if it's WAN_IF */
 			if(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat == WAN_IF)
diff --git a/ipacm/src/IPACM_Lan.cpp b/ipacm/src/IPACM_Lan.cpp
index 7e379d7..5a5aa7e 100644
--- a/ipacm/src/IPACM_Lan.cpp
+++ b/ipacm/src/IPACM_Lan.cpp
@@ -244,6 +244,7 @@
 					IPACMERR("Failed tell odu-driver the mode\n");
 				}
 				IPACMDBG("Tell odu-driver in router-mode(%d)\n", IPACM_Iface::ipacmcfg->ipacm_odu_router_mode);
+				IPACMDBG_H("odu is up: odu-driver in router-mode(%d) \n", IPACM_Iface::ipacmcfg->ipacm_odu_router_mode);
 				close(m_fd_odu);
 				IPACM_Lan::odu_up = true;
 		}
@@ -644,11 +645,12 @@
 		{
 			ipacm_event_data_all *data = (ipacm_event_data_all *)param;
 			ipa_interface_index = iface_ipa_index_query(data->if_index);
+			IPACMDBG_H("Recieved IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT event \n");
 			IPACMDBG_H("check iface %s category: %d\n",IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat);
 
 			if ((ipa_interface_index == ipa_if_num) && (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF))
 			{
-				IPACMDBG("ODU iface got v4-ip \n");
+				IPACMDBG_H("ODU iface got v4-ip \n");
 				/* first construc ODU full header */
 				if ((ipv4_header_set == false) && (ipv6_header_set == false))
 				{
@@ -657,19 +659,19 @@
 					if (IPACM_Iface::ipacmcfg->ipacm_odu_embms_enable == true)
 					{
 						handle_odu_route_add();
-						IPACMDBG("construct ODU header and route rules, embms_flag (%d) \n", IPACM_Iface::ipacmcfg->ipacm_odu_embms_enable);
+						IPACMDBG_H("construct ODU header and route rules, embms_flag (%d) \n", IPACM_Iface::ipacmcfg->ipacm_odu_embms_enable);
 					}
 					else
 					{
-						IPACMDBG("construct ODU header only, embms_flag (%d) \n", IPACM_Iface::ipacmcfg->ipacm_odu_embms_enable);
+						IPACMDBG_H("construct ODU header only, embms_flag (%d) \n", IPACM_Iface::ipacmcfg->ipacm_odu_embms_enable);
 					}
 				}
 				/* if ODU in bridge mode, directly return */
 				if(IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == false)
 				{
-				  return;
+					IPACMDBG_H("ODU is in bridge mode, no action \n");
+					return;
 				}
-
 			}
 
 			if (ipa_interface_index == ipa_if_num)
@@ -732,6 +734,14 @@
 
 			IPACMDBG_H("Received IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT event. \n");
 			IPACMDBG_H("check iface %s category: %d\n",IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat);
+			/* if ODU in bridge mode, directly return */
+			if ((ipa_interface_index == ipa_if_num) && (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF)
+					&& (IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == false))
+			{
+				IPACMDBG_H("ODU is in bridge mode, no action \n");
+				return;
+			}
+
 			if (ipa_interface_index == ipa_if_num)
 			{
 #ifdef FEATURE_ETH_BRIDGE_LE
@@ -760,7 +770,7 @@
 				eth_bridge_post_lan_client_event(data->mac_addr, IPA_ETH_BRIDGE_LAN_CLIENT_DEL_EVENT);
 				eth_bridge_del_lan_client(data->mac_addr);
 #endif
-				IPACMDBG_H("ETH iface delete client \n");
+				IPACMDBG_H("LAN iface delete client \n");
 				handle_eth_client_down_evt(data->mac_addr);
 				handle_lan2lan_client_active(data, IPA_LAN_CLIENT_INACTIVE);
 				return;
@@ -1096,7 +1106,6 @@
 		/* initial multicast/broadcast/fragment filter rule */
 #ifdef FEATURE_ETH_BRIDGE_LE
 		init_fl_rule(data->iptype);
-		eth_bridge_add_wlan_guest_ap_flt_rule(data->iptype);
 		eth_bridge_handle_dummy_wlan_client_flt_rule(data->iptype);
 		eth_bridge_handle_dummy_lan_client_flt_rule(data->iptype);
 		eth_bridge_install_cache_wlan_client_flt_rule(data->iptype);
@@ -1194,7 +1203,6 @@
 		{
 			/* initial multicast/broadcast/fragment filter rule */
 #ifdef FEATURE_ETH_BRIDGE_LE
-			eth_bridge_add_wlan_guest_ap_flt_rule(data->iptype);
 			eth_bridge_handle_dummy_wlan_client_flt_rule(data->iptype);
 			eth_bridge_handle_dummy_lan_client_flt_rule(data->iptype);
 			eth_bridge_install_cache_wlan_client_flt_rule(data->iptype);
@@ -1362,7 +1370,7 @@
 		flt_rule_entry.at_rear = true;
 		flt_rule_entry.flt_rule_hdl = -1;
 		flt_rule_entry.status = -1;
-		if(IPACM_Wan::cradle_backhaul_is_wan_bridge == true)
+		if(IPACM_Wan::isWan_Bridge_Mode())
 		{
 			flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
 		}
@@ -1520,7 +1528,7 @@
 	char index[ETH_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_eth_client_index(mac_addr);
@@ -2020,11 +2028,9 @@
 		            				 get_client_memptr(eth_client, eth_index)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[v6_num], iptype);
 
 			        /*Copy same rule to v6 WAN RT TBL*/
-  	                strncpy(rt_rule->rt_tbl_name,
-  	                 					IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name,
-  	                 					sizeof(rt_rule->rt_tbl_name));
+				strncpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, sizeof(rt_rule->rt_tbl_name));
 
-                    /* Downlink traffic from Wan iface, directly through IPA */
+				/* Downlink traffic from Wan iface, directly through IPA */
 					rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
 			        memcpy(&rt_rule_entry->rule.attrib,
 						 &tx_prop->tx[tx_index].attrib,
@@ -2250,7 +2256,7 @@
 
 	if(tx_prop == NULL)
 	{
-	  IPACMDBG("No tx properties, ignore default route setting\n");
+	  IPACMDBG_H("No tx properties, ignore default route setting\n");
 	  return IPACM_SUCCESS;
 	}
 
@@ -2268,25 +2274,25 @@
 	rt_rule->num_rules = (uint8_t)NUM;
 
 
-	IPACMDBG(" WAN table created %s \n", rt_rule->rt_tbl_name);
+	IPACMDBG_H("WAN table created %s \n", rt_rule->rt_tbl_name);
 	rt_rule_entry = &rt_rule->rules[0];
 	rt_rule_entry->at_rear = true;
 
 	for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
 	{
 
-	    if (IPA_IP_v4 == tx_prop->tx[tx_index].ip)
-	    {
-	    	strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_odu_v4.name);
+		if (IPA_IP_v4 == tx_prop->tx[tx_index].ip)
+		{
+			strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_odu_v4.name);
 			rt_rule_entry->rule.hdr_hdl = ODU_hdr_hdl_v4;
 			rt_rule->ip = IPA_IP_v4;
-	    }
-	    else
-	    {
-	    	strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_odu_v6.name);
+		}
+		else
+		{
+			strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_odu_v6.name);
 			rt_rule_entry->rule.hdr_hdl = ODU_hdr_hdl_v6;
 			rt_rule->ip = IPA_IP_v6;
-	    }
+		}
 
 		rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
 		memcpy(&rt_rule_entry->rule.attrib,
@@ -2300,13 +2306,13 @@
 			rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0;
 
 			if (false == m_routing.AddRoutingRule(rt_rule))
-		    {
-		    	IPACMERR("Routing rule addition failed!\n");
-		    	free(rt_rule);
-		    	return IPACM_FAILURE;
-		    }
+			{
+				IPACMERR("Routing rule addition failed!\n");
+				free(rt_rule);
+				return IPACM_FAILURE;
+			}
 			odu_route_rule_v4_hdl[tx_index] = rt_rule_entry->rt_rule_hdl;
-		    IPACMDBG("Got ipv4 ODU-route rule hdl:0x%x,tx:%d,ip-type: %d \n",
+			IPACMDBG_H("Got ipv4 ODU-route rule hdl:0x%x,tx:%d,ip-type: %d \n",
 						 odu_route_rule_v4_hdl[tx_index],
 						 tx_index,
 						 IPA_IP_v4);
@@ -2323,18 +2329,17 @@
 			rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0;
 
 			if (false == m_routing.AddRoutingRule(rt_rule))
-		    {
-		    	IPACMERR("Routing rule addition failed!\n");
-		    	free(rt_rule);
-		    	return IPACM_FAILURE;
+			{
+				IPACMERR("Routing rule addition failed!\n");
+				free(rt_rule);
+				return IPACM_FAILURE;
 			}
 			odu_route_rule_v6_hdl[tx_index] = rt_rule_entry->rt_rule_hdl;
-			IPACMDBG("Set ipv6 ODU-route rule hdl for v6_lan_table:0x%x,tx:%d,ip-type: %d \n",
-		                 odu_route_rule_v6_hdl[tx_index],
-		                 tx_index,
-		                 IPA_IP_v6);
+			IPACMDBG_H("Set ipv6 ODU-route rule hdl for v6_lan_table:0x%x,tx:%d,ip-type: %d \n",
+					odu_route_rule_v6_hdl[tx_index],
+					tx_index,
+					IPA_IP_v6);
 		}
-
 	}
 	free(rt_rule);
 	return IPACM_SUCCESS;
@@ -2347,37 +2352,37 @@
 
 	if(tx_prop == NULL)
 	{
-	  IPACMDBG("No tx properties, ignore delete default route setting\n");
-	  return IPACM_SUCCESS;
+		IPACMDBG_H("No tx properties, ignore delete default route setting\n");
+		return IPACM_SUCCESS;
 	}
 
-		for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
+	for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
+	{
+		if (tx_prop->tx[tx_index].ip == IPA_IP_v4)
 		{
-			if (tx_prop->tx[tx_index].ip == IPA_IP_v4)
-			{
-		    	IPACMDBG("Tx:%d, ip-type: %d match ip-type: %d, RT-rule deleted\n",
-		    					    tx_index, tx_prop->tx[tx_index].ip,IPA_IP_v4);
+			IPACMDBG_H("Tx:%d, ip-type: %d match ip-type: %d, RT-rule deleted\n",
+					tx_index, tx_prop->tx[tx_index].ip,IPA_IP_v4);
 
-				if (m_routing.DeleteRoutingHdl(odu_route_rule_v4_hdl[tx_index], IPA_IP_v4)
-						== false)
-				{
-					IPACMDBG("IP-family:%d, Routing rule(hdl:0x%x) deletion failed with tx_index %d!\n", IPA_IP_v4, odu_route_rule_v4_hdl[tx_index], tx_index);
-					return IPACM_FAILURE;
-				}
-			}
-			else
+			if (m_routing.DeleteRoutingHdl(odu_route_rule_v4_hdl[tx_index], IPA_IP_v4)
+					== false)
 			{
-		    	IPACMDBG("Tx:%d, ip-type: %d match ip-type: %d, RT-rule deleted\n",
-		    					    tx_index, tx_prop->tx[tx_index].ip,IPA_IP_v6);
-
-				if (m_routing.DeleteRoutingHdl(odu_route_rule_v6_hdl[tx_index], IPA_IP_v6)
-						== false)
-				{
-					IPACMDBG("IP-family:%d, Routing rule(hdl:0x%x) deletion failed with tx_index %d!\n", IPA_IP_v6, odu_route_rule_v6_hdl[tx_index], tx_index);
-					return IPACM_FAILURE;
-				}
+				IPACMERR("IP-family:%d, Routing rule(hdl:0x%x) deletion failed with tx_index %d!\n", IPA_IP_v4, odu_route_rule_v4_hdl[tx_index], tx_index);
+				return IPACM_FAILURE;
 			}
 		}
+		else
+		{
+			IPACMDBG_H("Tx:%d, ip-type: %d match ip-type: %d, RT-rule deleted\n",
+					tx_index, tx_prop->tx[tx_index].ip,IPA_IP_v6);
+
+			if (m_routing.DeleteRoutingHdl(odu_route_rule_v6_hdl[tx_index], IPA_IP_v6)
+					== false)
+			{
+				IPACMERR("IP-family:%d, Routing rule(hdl:0x%x) deletion failed with tx_index %d!\n", IPA_IP_v6, odu_route_rule_v6_hdl[tx_index], tx_index);
+				return IPACM_FAILURE;
+			}
+		}
+	}
 
 	return IPACM_SUCCESS;
 }
@@ -2514,12 +2519,13 @@
 	int res = IPACM_SUCCESS;
 	uint32_t temp_eth_bridge_flt_rule[IPA_LAN_TO_LAN_MAX_WLAN_CLIENT];
 
+	IPACMDBG_H("lan handle_down_evt\n ");
 	if (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF)
 	{
 		/* delete ODU default RT rules */
 		if (IPACM_Iface::ipacmcfg->ipacm_odu_embms_enable == true)
 		{
-			IPACMDBG_H(" eMBMS enable, delete eMBMS DL RT rule\n");
+			IPACMDBG_H("eMBMS enable, delete eMBMS DL RT rule\n");
 			handle_odu_route_del();
 		}
 
@@ -2529,11 +2535,11 @@
 			if (m_header.DeleteHeaderHdl(ODU_hdr_hdl_v4)
 					== false)
 			{
-					IPACMDBG("ODU ipv4 header delete fail\n");
+					IPACMERR("ODU ipv4 header delete fail\n");
 					res = IPACM_FAILURE;
 					goto fail;
 			}
-			IPACMDBG("ODU ipv4 header delete success\n");
+			IPACMDBG_H("ODU ipv4 header delete success\n");
 		}
 
 		if (ipv6_header_set)
@@ -2541,11 +2547,11 @@
 			if (m_header.DeleteHeaderHdl(ODU_hdr_hdl_v6)
 					== false)
 			{
-				IPACMDBG("ODU ipv6 header delete fail\n");
+				IPACMERR("ODU ipv6 header delete fail\n");
 				res = IPACM_FAILURE;
 				goto fail;
 			}
-			IPACMDBG("ODU ipv6 header delete success\n");
+			IPACMERR("ODU ipv6 header delete success\n");
 		}
 	}
 
@@ -2554,7 +2560,6 @@
 	{
 		goto fail;
 	}
-	IPACMDBG_H("lan handle_down_evt\n ");
 
 #ifdef FEATURE_ETH_BRIDGE_LE
 	if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == LAN_IF)
@@ -2701,7 +2706,7 @@
 		IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
 #endif
 	}
-    IPACMDBG_H("Finished delete default iface ipv4 filtering rules \n ");
+	IPACMDBG_H("Finished delete default iface ipv4 filtering rules \n ");
 
 	if (ip_type != IPA_IP_v4 && rx_prop != NULL)
 	{
@@ -2786,7 +2791,7 @@
 		IPACMDBG_H("Deleted lan2lan IPv6 flt rules.\n");
 #endif
 	}
-    IPACMDBG_H("Finished delete default iface ipv6 filtering rules \n ");
+	IPACMDBG_H("Finished delete default iface ipv6 filtering rules \n ");
 
 	if (ip_type != IPA_IP_v6)
 	{
@@ -3037,7 +3042,18 @@
 	flt_rule_entry.rule.to_uc = 0;
 	flt_rule_entry.rule.eq_attrib_type = 1;
 	if(iptype == IPA_IP_v4)
-		flt_rule_entry.rule.action = IPA_PASS_TO_SRC_NAT;
+	{
+		if (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF &&
+			IPACM_Wan::isWan_Bridge_Mode())
+		{
+			IPACMDBG_H("WAN, ODU are in bridge mode \n");
+			flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
+		}
+		else
+		{
+			flt_rule_entry.rule.action = IPA_PASS_TO_SRC_NAT;
+		}
+	}
 	else if(iptype == IPA_IP_v6)
 		flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
 	else
@@ -5824,6 +5840,11 @@
 		if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == LAN_IF ||
 			(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF))
 		{
+			if(IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == false)
+			{
+				IPACMDBG_H("ODU is in bridge mode, do not set CPE to USB and USB to CPE hdr proc ctx.\n");
+				return res;
+			}
 			if(IPACM_Lan::is_cpe_up == true && IPACM_Lan::is_usb_up == true &&
 				IPACM_Lan::cpe_to_usb_hdr_proc_ctx.valid == false && IPACM_Lan::usb_to_cpe_hdr_proc_ctx.valid == false)
 			{
diff --git a/ipacm/src/IPACM_Wan.cpp b/ipacm/src/IPACM_Wan.cpp
index e5cc958..51f9bc3 100644
--- a/ipacm/src/IPACM_Wan.cpp
+++ b/ipacm/src/IPACM_Wan.cpp
@@ -67,7 +67,7 @@
 int IPACM_Wan::num_ipv6_modem_pdn = 0;
 
 bool IPACM_Wan::embms_is_on = false;
-bool IPACM_Wan::cradle_backhaul_is_wan_bridge = false;
+bool IPACM_Wan::backhaul_is_wan_bridge = false;
 
 uint32_t IPACM_Wan::backhaul_ipv6_prefix[2];
 
@@ -528,15 +528,15 @@
 				IPACMDBG_H("Now the cradle wan mode is %d.\n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode);
 				if(is_default_gateway == true)
 				{
-					if(cradle_backhaul_is_wan_bridge == false && IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode == BRIDGE)
+					if(backhaul_is_wan_bridge == false && IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode == BRIDGE)
 					{
 						IPACMDBG_H("Cradle wan mode switch to bridge mode.\n");
-						cradle_backhaul_is_wan_bridge = true;
+						backhaul_is_wan_bridge = true;
 					}
-					else if(cradle_backhaul_is_wan_bridge == true && IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode == ROUTER)
+					else if(backhaul_is_wan_bridge == true && IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode == ROUTER)
 					{
 						IPACMDBG_H("Cradle wan mode switch to router mode.\n");
-						cradle_backhaul_is_wan_bridge = false;
+						backhaul_is_wan_bridge = false;
 					}
 					else
 					{
@@ -1128,17 +1128,20 @@
 	memcpy(backhaul_ipv6_prefix, ipv6_prefix, sizeof(backhaul_ipv6_prefix));
 	IPACMDBG_H("Setup backhaul ipv6 prefix to be 0x%08x%08x.\n", backhaul_ipv6_prefix[0], backhaul_ipv6_prefix[1]);
 
+	if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode == BRIDGE)
+	{
+		IPACM_Wan::backhaul_is_wan_bridge = true;
+	}
+	else
+	{
+		IPACM_Wan::backhaul_is_wan_bridge = false;
+	}
+	IPACMDBG_H("backhaul_is_wan_bridge ?: %d \n", IPACM_Wan::backhaul_is_wan_bridge);
+
 	if (m_is_sta_mode !=Q6_WAN)
 	{
 		IPACM_Wan::backhaul_is_sta_mode	= true;
-		if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode == BRIDGE)
-		{
-			IPACM_Wan::cradle_backhaul_is_wan_bridge = true;
-		}
-		else
-		{
-			IPACM_Wan::cradle_backhaul_is_wan_bridge = false;
-		}
+
 		if((iptype==IPA_IP_v4) && (header_set_v4 != true))
 		{
 			header_partial_default_wan_v4 = true;
@@ -2518,7 +2521,15 @@
 		}
 		else
 		{
-			flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT;
+			if(isWan_Bridge_Mode())
+			{
+				IPACMDBG_H("ODU is in bridge mode. \n");
+				flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
+			}
+			else
+			{
+				flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT;
+			}
 		}
 
 		memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx));
@@ -2894,8 +2905,7 @@
 		memcpy(&flt_rule_entry.rule.attrib,
 					 &rx_prop->rx[0].attrib,
 					 sizeof(flt_rule_entry.rule.attrib));
-		/* remove meta data mask */
-		flt_rule_entry.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA);
+		/* Multiple PDNs may exist so keep meta-data */
 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_PROTOCOL;
 		flt_rule_entry.rule.attrib.u.v4.protocol = (uint8_t)IPACM_FIREWALL_IPPROTO_ICMP;
 
@@ -3011,8 +3021,7 @@
 		memcpy(&flt_rule_entry.rule.attrib,
 					 &rx_prop->rx[1].attrib,
 					 sizeof(flt_rule_entry.rule.attrib));
-		/* remove meta data mask */
-		flt_rule_entry.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA);
+		/* Multiple PDNs may exist so keep meta-data */
 		flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR;
 		flt_rule_entry.rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_ICMP6;
 
diff --git a/ipacm/src/IPACM_Wlan.cpp b/ipacm/src/IPACM_Wlan.cpp
index 7256a88..e58345a 100644
--- a/ipacm/src/IPACM_Wlan.cpp
+++ b/ipacm/src/IPACM_Wlan.cpp
@@ -186,7 +186,8 @@
 			{
 				is_guest_ap = true;
 			}
-			IPACMDBG_H("Guest ap enable: %d\n",is_guest_ap);
+			IPACMDBG_H("%s: guest ap enable: %d \n",
+				IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, is_guest_ap);
 		}
 	}
 #endif
@@ -429,9 +430,6 @@
 		IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta);
 		if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
 		{
-#ifdef FEATURE_ETH_BRIDGE_LE
-			eth_bridge_install_wlan_guest_ap_ipv6_flt_rule();
-#endif
 			if(wlan_ap_index == 0) //install ipv6 prefix rule only once
 			{
 				install_ipv6_prefix_flt_rule(data_wan->ipv6_prefix);
@@ -522,26 +520,26 @@
 				{
 					if(data->attribs[i].attrib_type == WLAN_HDR_ATTRIB_MAC_ADDR)
 					{
+						if(IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.valid == true)
+						{
+							eth_bridge_add_wlan_client_rt_rule(data->attribs[i].u.mac_addr, SRC_WLAN, IPA_IP_v4);
+							eth_bridge_add_wlan_client_rt_rule(data->attribs[i].u.mac_addr, SRC_WLAN, IPA_IP_v6);
+						}
+						if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
+						{
+							eth_bridge_add_self_client_flt_rule(data->attribs[i].u.mac_addr, IPA_IP_v4);
+						}
+						if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
+						{
+							eth_bridge_add_self_client_flt_rule(data->attribs[i].u.mac_addr, IPA_IP_v6);
+						}
 						if (is_guest_ap == false)
 						{
-							if(IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.valid == true)
-							{
-								eth_bridge_add_wlan_client_rt_rule(data->attribs[i].u.mac_addr, SRC_WLAN, IPA_IP_v4);
-								eth_bridge_add_wlan_client_rt_rule(data->attribs[i].u.mac_addr, SRC_WLAN, IPA_IP_v6);
-							}
 							if(IPACM_Lan::lan_to_wlan_hdr_proc_ctx.valid == true)
 							{
 								eth_bridge_add_wlan_client_rt_rule(data->attribs[i].u.mac_addr, SRC_LAN, IPA_IP_v4);
 								eth_bridge_add_wlan_client_rt_rule(data->attribs[i].u.mac_addr, SRC_LAN, IPA_IP_v6);
 							}
-							if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
-							{
-								eth_bridge_add_self_client_flt_rule(data->attribs[i].u.mac_addr, IPA_IP_v4);
-							}
-							if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
-							{
-								eth_bridge_add_self_client_flt_rule(data->attribs[i].u.mac_addr, IPA_IP_v6);
-							}
 							eth_bridge_post_lan_client_event(data->attribs[i].u.mac_addr, IPA_ETH_BRIDGE_WLAN_CLIENT_ADD_EVENT);
 						}
 						eth_bridge_add_wlan_client(data->attribs[i].u.mac_addr, ipa_if_num);
@@ -563,14 +561,14 @@
 			{
 				IPACMDBG_H("Received IPA_WLAN_CLIENT_DEL_EVENT\n");
 #ifdef FEATURE_ETH_BRIDGE_LE
+				eth_bridge_del_self_client_flt_rule(data->mac_addr);
+				eth_bridge_del_wlan_client_rt_rule(data->mac_addr, SRC_WLAN);
 				if (is_guest_ap == false)
 				{
-					eth_bridge_del_wlan_client_rt_rule(data->mac_addr, SRC_WLAN);
 					if(IPACM_Lan::lan_to_wlan_hdr_proc_ctx.valid == true)
 					{
 						eth_bridge_del_wlan_client_rt_rule(data->mac_addr, SRC_LAN);
 					}
-					eth_bridge_del_self_client_flt_rule(data->mac_addr);
 					eth_bridge_post_lan_client_event(data->mac_addr, IPA_ETH_BRIDGE_WLAN_CLIENT_DEL_EVENT);
 				}
 				eth_bridge_del_wlan_client(data->mac_addr);
@@ -834,11 +832,11 @@
 	break;
 	case IPA_CFG_CHANGE_EVENT:
 	{
+		int i;
 		IPACMDBG_H("Received IPA_CFG_CHANGE_EVENT event for %s with new wlan-mode: %s old wlan-mode: %s",
 				IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name,
 				(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].wlan_mode == 0) ? "full" : "internet",
 				(is_guest_ap == true) ? "internet" : "full");
-
 		if (is_guest_ap == true && (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].wlan_mode == FULL))
 		{
 			is_guest_ap = false;
@@ -855,10 +853,30 @@
 		{
 			IPACMDBG_H("No change in %s access mode. \n",
 					IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name);
+
+			/* Handle the WLAN filtering rule */
+			for (i=0; i<IPACM_Lan::num_wlan_client; i++)
+			{
+				if (IPACM_Lan::eth_bridge_wlan_client[i].ipa_if_num == ipa_if_num)
+				{
+					eth_bridge_modify_wlan_client_flt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac, DST_WLAN, IPA_IP_v4);
+					eth_bridge_modify_wlan_client_flt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac, DST_WLAN, IPA_IP_v6);
+				}
+			}
+			/* Handle the LAN filtering rule */
+			if (wlan_ap_index == 0 && is_guest_ap == false)
+			{
+				IPACMDBG_H("Modify LAN clients filtering rules. \n");
+				for (i=0; i<IPACM_Lan::num_lan_client; i++)
+				{
+					eth_bridge_modify_wlan_client_flt_rule(IPACM_Lan::eth_bridge_lan_client[i].mac, DST_LAN, IPA_IP_v4);
+					eth_bridge_modify_wlan_client_flt_rule(IPACM_Lan::eth_bridge_lan_client[i].mac, DST_LAN, IPA_IP_v6);
+				}
+			}
+			IPACMDBG_H("wlan access mode switch is successful. \n");
 		}
 	}
 	break;
-
 	default:
 		break;
 	}
@@ -2512,13 +2530,13 @@
 	for (i = 0; i < num_wifi_client; i++)
 	{
 #ifdef FEATURE_ETH_BRIDGE_LE
+		eth_bridge_del_self_client_flt_rule(get_client_memptr(wlan_client, i)->mac);
+		eth_bridge_del_wlan_client_rt_rule(get_client_memptr(wlan_client, i)->mac, SRC_WLAN);
 		eth_bridge_del_wlan_client(get_client_memptr(wlan_client, i)->mac);
 		if (is_guest_ap == false)
 		{
-			eth_bridge_del_self_client_flt_rule(get_client_memptr(wlan_client, i)->mac);
-			eth_bridge_post_lan_client_event(get_client_memptr(wlan_client, i)->mac, IPA_ETH_BRIDGE_WLAN_CLIENT_DEL_EVENT);
-			eth_bridge_del_wlan_client_rt_rule(get_client_memptr(wlan_client, i)->mac, SRC_WLAN);
 			eth_bridge_del_wlan_client_rt_rule(get_client_memptr(wlan_client, i)->mac, SRC_LAN);
+			eth_bridge_post_lan_client_event(get_client_memptr(wlan_client, i)->mac, IPA_ETH_BRIDGE_WLAN_CLIENT_DEL_EVENT);
 		}
 #endif
 		/* First reset nat rules and then route rules */
@@ -3735,6 +3753,11 @@
 		IPACMERR("MAC address is empty.\n");
 		return IPACM_FAILURE;
 	}
+	if(is_guest_ap)
+	{
+		IPACMDBG_H("This is guest AP WLAN interface index %d, ignore.\n", wlan_ap_index);
+		return IPACM_SUCCESS;
+	}
 	if(wlan_ap_index != 0)
 	{
 		IPACMDBG_H("This is WLAN interface index %d, ignore.\n", wlan_ap_index);
@@ -3812,7 +3835,14 @@
 	}
 
 	memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib));
-	flt_rule.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA);	//remove meta data mask
+
+	/* Install meta-data if self or other ap is guest ap */
+	if ((is_guest_ap == false &&  IPACM_Wlan::num_wlan_ap_iface == 1) ||
+			IPACM_Iface::ipacmcfg->ipa_num_wlan_guest_ap == 0)
+	{
+		flt_rule.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA);	//remove meta data mask
+	}
+
 	if(IPACM_Lan::wlan_hdr_type == IPA_HDR_L2_ETHERNET_II)
 	{
 		flt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II;
@@ -4079,7 +4109,14 @@
 	}
 
 	memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib));
-	flt_rule.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA);	//remove meta data mask
+
+	/* Install meta-data if self or other ap is guest ap */
+	if ((is_guest_ap == false &&  IPACM_Wlan::num_wlan_ap_iface == 1) ||
+		IPACM_Iface::ipacmcfg->ipa_num_wlan_guest_ap == 0)
+	{
+		flt_rule.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA);	//remove meta data mask
+	}
+
 	if(IPACM_Lan::wlan_hdr_type == IPA_HDR_L2_ETHERNET_II)
 	{
 		flt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II;
@@ -4288,6 +4325,10 @@
 		IPACMERR("Client MAC address is empty.\n");
 		return IPACM_FAILURE;
 	}
+
+	IPACMDBG_H("Receive WLAN client MAC 0x%02x%02x%02x%02x%02x%02x src_iface: %d .\n",
+			mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], src);
+
 	if(iptype == IPA_IP_v4)
 	{
 		if( (src == SRC_WLAN && wlan_client_rt_from_wlan_info_count_v4 == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT)
@@ -4313,8 +4354,6 @@
 		return IPACM_FAILURE;
 	}
 
-	IPACMDBG_H("Receive WLAN client MAC 0x%02x%02x%02x%02x%02x%02x.\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
-
 	int i, len, res = IPACM_SUCCESS;
 	struct ipa_ioc_add_rt_rule* rt_rule_table = NULL;
 	struct ipa_rt_rule_add rt_rule;
@@ -5056,8 +5095,8 @@
 		return IPACM_FAILURE;
 	}
 
-	IPACMDBG_H("Receive WLAN client MAC 0x%02x%02x%02x%02x%02x%02x.\n",
-			mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+	IPACMDBG_H("Receive WLAN client MAC 0x%02x%02x%02x%02x%02x%02x. src_iface: %d\n",
+			mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], src_iface);
 
 	if (iptype == IPA_IP_v4)
 	{
@@ -5267,68 +5306,229 @@
 {
 	int i;
 
-	if (is_guest_ap == true) /* Wlan internet mode */
+	for (i=0; i<IPACM_Lan::num_wlan_client; i++)
 	{
-		IPACMDBG_H("Install wlan guest ap IPv4 flt rules.\n");
-		eth_bridge_add_wlan_guest_ap_flt_rule(IPA_IP_v4);
-		IPACMDBG_H("Install wlan guest ap IPv6 flt rules.\n");
-		eth_bridge_add_wlan_guest_ap_flt_rule(IPA_IP_v6);
-
-		for (i=0; i<IPACM_Lan::num_wlan_client; i++)
+		if (IPACM_Lan::eth_bridge_wlan_client[i].ipa_if_num == ipa_if_num)
 		{
-			if (IPACM_Lan::eth_bridge_wlan_client[i].ipa_if_num == ipa_if_num)
+			eth_bridge_modify_wlan_client_flt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac, DST_WLAN, IPA_IP_v4);
+			eth_bridge_modify_wlan_client_flt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac, DST_WLAN, IPA_IP_v6);
+
+			if(IPACM_Lan::lan_to_wlan_hdr_proc_ctx.valid == true)
 			{
-				eth_bridge_del_wlan_client_rt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac, SRC_WLAN);
-				if(IPACM_Lan::lan_to_wlan_hdr_proc_ctx.valid == true)
+				if (is_guest_ap == true)
 				{
 					eth_bridge_del_wlan_client_rt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac, SRC_LAN);
+					eth_bridge_post_lan_client_event(IPACM_Lan::eth_bridge_wlan_client[i].mac, IPA_ETH_BRIDGE_WLAN_CLIENT_DEL_EVENT);
 				}
-				eth_bridge_del_self_client_flt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac);
-				eth_bridge_post_lan_client_event(IPACM_Lan::eth_bridge_wlan_client[i].mac, IPA_ETH_BRIDGE_WLAN_CLIENT_DEL_EVENT);
-			}
-		}
-	}
-	else /* Wlan full mode */
-	{
-		if (IPACM_Iface::ipacmcfg->ipa_num_wlan_guest_ap == 0)
-		{
-			IPACMDBG_H("Delete wlan guest ap IPv4 flt rules.\n");
-			for (i=0; i<IPACM_Iface::ipacmcfg->ipa_num_private_subnet; i++)
-			{
-				if (reset_to_dummy_flt_rule(IPA_IP_v4, wlan_guest_ap_flt_rule_hdl_v4[i]) == IPACM_FAILURE)
-				{
-					IPACMERR("Error deleting wlan guest ap IPv4 flt rules.\n");
-					return;
-				}
-			}
-			IPACMDBG_H("Delete wlan guest ap IPv6 filter rules. \n");
-			for (i=0; i<IPA_GUEST_AP_IPv6_FLT_RULE_ENTRIES; i++)
-			{
-				if (reset_to_dummy_flt_rule(IPA_IP_v6, wlan_guest_ap_flt_rule_hdl_v6[i]) == IPACM_FAILURE)
-				{
-					IPACMERR("Error deleting wlan guest ap IPv6 flt rules.\n");
-					return;
-				}
-				wlan_guest_ap_flt_rule_hdl_v6[i] = 0;
-			}
-		}
-
-		for (i=0; i<IPACM_Lan::num_wlan_client; i++)
-		{
-			if (IPACM_Lan::eth_bridge_wlan_client[i].ipa_if_num == ipa_if_num)
-			{
-				eth_bridge_add_wlan_client_rt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac, SRC_WLAN, IPA_IP_v4);
-				eth_bridge_add_wlan_client_rt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac, SRC_WLAN, IPA_IP_v6);
-				if(IPACM_Lan::lan_to_wlan_hdr_proc_ctx.valid == true)
+				else
 				{
 					eth_bridge_add_wlan_client_rt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac, SRC_LAN, IPA_IP_v4);
 					eth_bridge_add_wlan_client_rt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac, SRC_LAN, IPA_IP_v6);
+					eth_bridge_post_lan_client_event(IPACM_Lan::eth_bridge_wlan_client[i].mac, IPA_ETH_BRIDGE_WLAN_CLIENT_ADD_EVENT);
 				}
-				eth_bridge_add_self_client_flt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac, IPA_IP_v4);
-				eth_bridge_add_self_client_flt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac, IPA_IP_v6);
-				eth_bridge_post_lan_client_event(IPACM_Lan::eth_bridge_wlan_client[i].mac, IPA_ETH_BRIDGE_WLAN_CLIENT_ADD_EVENT);
 			}
 		}
 	}
-	IPACMDBG_H("Wlan mode switch is successful. ");
+}
+
+
+int IPACM_Wlan::eth_bridge_modify_wlan_client_flt_rule(uint8_t* mac, eth_bridge_dst_iface dst_iface, ipa_ip_type iptype)
+{
+
+	int index, len, res = IPACM_SUCCESS, client_position;
+	struct ipa_flt_rule_mdfy flt_rule;
+	struct ipa_ioc_mdfy_flt_rule* pFilteringTable = NULL;
+
+	if (rx_prop == NULL)
+	{
+		IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
+		return IPACM_FAILURE;
+	}
+	if (mac == NULL)
+	{
+		IPACMERR("MAC address is empty.\n");
+		return IPACM_FAILURE;
+	}
+	IPACMDBG_H("Received client MAC 0x%02x%02x%02x%02x%02x%02x. dst_iface: %d \n",
+			mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], dst_iface);
+
+	if (dst_iface == DST_WLAN && IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.valid == false)
+	{
+		IPACMDBG_H("WLAN to WLAN hdr proc ctx has not been set, don't modify client specific flt rule.\n");
+		return IPACM_FAILURE;
+	}
+	if (dst_iface == DST_LAN && IPACM_Lan::lan_to_wlan_hdr_proc_ctx.valid == false)
+	{
+		IPACMDBG_H("WLAN to LAN hdr proc ctx has not been set, don't modify client specific flt rule.\n");
+		return IPACM_FAILURE;
+	}
+
+	if (dst_iface == DST_WLAN)
+	{
+		for (index=0; index<wlan_client_flt_info_count; index++)
+		{
+			if(memcmp(eth_bridge_wlan_client_flt_info[index].mac, mac, sizeof(eth_bridge_wlan_client_flt_info[index].mac)) == 0)
+			{
+				client_position = index;
+				IPACMDBG_H("The client is found at position %d.\n", client_position);
+				break;
+			}
+		}
+		if(index == wlan_client_flt_info_count)
+		{
+			IPACMDBG_H("The wlan client is not found.\n");
+			return IPACM_FAILURE;
+		}
+	}
+	else
+	{
+		for(index=0; index<lan_client_flt_info_count; index++)
+		{
+			if(memcmp(eth_bridge_lan_client_flt_info[index].mac, mac, sizeof(eth_bridge_lan_client_flt_info[index].mac)) == 0)
+			{
+				client_position = index;
+				IPACMDBG_H("The client is found at position %d.\n", client_position);
+				break;
+			}
+		}
+		if(index == lan_client_flt_info_count)
+		{
+			IPACMDBG_H("The lan client is not found.\n");
+			return IPACM_FAILURE;
+		}
+	}
+
+	len = sizeof(struct ipa_ioc_mdfy_flt_rule) + sizeof(struct ipa_flt_rule_mdfy);
+	pFilteringTable = (struct ipa_ioc_mdfy_flt_rule*)malloc(len);
+	if (!pFilteringTable)
+	{
+		IPACMERR("Failed to allocate ipa_ioc_mdfy_flt_rule memory...\n");
+		return IPACM_FAILURE;
+	}
+	memset(pFilteringTable, 0, len);
+
+	/* add mac based rule on IPv4 table */
+	pFilteringTable->commit = 1;
+	pFilteringTable->ip = iptype;
+	pFilteringTable->num_rules = 1;
+
+	/* point to WLAN-WLAN routing table */
+	memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy));
+	flt_rule.status = -1;
+	flt_rule.rule.retain_hdr = 0;
+	flt_rule.rule.to_uc = 0;
+	flt_rule.rule.action = IPA_PASS_TO_ROUTING;
+	flt_rule.rule.eq_attrib_type = 0;
+
+	if (dst_iface == DST_WLAN)
+	{
+		if(iptype == IPA_IP_v4)
+		{
+			if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v4))
+			{
+				IPACMERR("Failed to get routing table handle.\n");
+				res = IPACM_FAILURE;
+				goto fail;
+			}
+			flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v4.hdl;
+			IPACMDBG_H("WLAN->WLAN IPv4 filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v4.name);
+		}
+		else
+		{
+			if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v6))
+			{
+				IPACMERR("Failed to get routing table handle.\n");
+				res = IPACM_FAILURE;
+				goto fail;
+			}
+			flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v6.hdl;
+			IPACMDBG_H("WLAN->WLAN IPv6 filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v6.name);
+		}
+	}
+	else
+	{
+		if(iptype == IPA_IP_v4)
+		{
+			if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_wlan_v4))
+			{
+				IPACMERR("Failed to get routing table handle.\n");
+				res = IPACM_FAILURE;
+				goto fail;
+			}
+			flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_wlan_v4.hdl;
+			IPACMDBG_H("WLAN->LAN IPv4 filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_wlan_v4.name);
+		}
+		else
+		{
+			if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_wlan_v6))
+			{
+				IPACMERR("Failed to get routing table handle.\n");
+				res = IPACM_FAILURE;
+			}
+			flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_wlan_v6.hdl;
+			IPACMDBG_H("WLAN->LAN IPv6 filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_wlan_v6.name);
+		}
+	}
+
+	memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib));
+
+	/* Install meta-data if self or other ap is guest ap */
+	if ((is_guest_ap == false &&  IPACM_Wlan::num_wlan_ap_iface == 1) ||
+			IPACM_Iface::ipacmcfg->ipa_num_wlan_guest_ap == 0)
+	{
+		flt_rule.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA); //remove meta data mask
+	}
+
+	if(IPACM_Lan::wlan_hdr_type == IPA_HDR_L2_ETHERNET_II)
+	{
+		flt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II;
+	}
+	else if(IPACM_Lan::wlan_hdr_type == IPA_HDR_L2_802_3)
+	{
+		flt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3;
+	}
+	else
+	{
+		IPACMERR("WLAN hdr type is not expected.\n");
+		res = IPACM_FAILURE;
+		goto fail;
+	}
+	memcpy(flt_rule.rule.attrib.dst_mac_addr, mac, sizeof(flt_rule.rule.attrib.dst_mac_addr));
+	memset(flt_rule.rule.attrib.dst_mac_addr_mask, 0xFF, sizeof(flt_rule.rule.attrib.dst_mac_addr_mask));
+
+	if (dst_iface == DST_WLAN)
+	{
+		if(iptype == IPA_IP_v4)
+		{
+			flt_rule.rule_hdl = eth_bridge_wlan_client_flt_info[client_position].flt_rule_hdl_v4;
+		}
+		else
+		{
+			flt_rule.rule_hdl = eth_bridge_wlan_client_flt_info[client_position].flt_rule_hdl_v6;
+		}
+	}
+	else
+	{
+		if(iptype == IPA_IP_v4)
+		{
+			flt_rule.rule_hdl = eth_bridge_lan_client_flt_info[client_position].flt_rule_hdl_v4;
+		}
+		else
+		{
+			flt_rule.rule_hdl = eth_bridge_lan_client_flt_info[client_position].flt_rule_hdl_v6;
+		}
+	}
+	memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy));
+	if (false == m_filtering.ModifyFilteringRule(pFilteringTable))
+	{
+		IPACMERR("Failed to modify wlan client filtering rule.\n");
+		res = IPACM_FAILURE;
+		goto fail;
+	}
+fail:
+	if(pFilteringTable == NULL)
+	{
+		free(pFilteringTable);
+	}
+	return res;
 }
diff --git a/ipacm/src/IPACM_cfg.xml b/ipacm/src/IPACM_cfg.xml
index f419b1b..b4a236e 100644
--- a/ipacm/src/IPACM_cfg.xml
+++ b/ipacm/src/IPACM_cfg.xml
@@ -18,6 +18,7 @@
 			<Iface>
 			   <Name>rmnet_data0</Name>
 			   <Category>WAN</Category>
+			   <Mode>ROUTER</Mode>
 			</Iface>
 			<Iface>
 			   <Name>rmnet_data1</Name>
@@ -55,7 +56,7 @@
 			<Iface>
 			   <Name>wlan1</Name>
 			   <Category>UNKNOWN</Category>
-			   <WlanMode>internet</WlanMode>
+			   <WlanMode>full</WlanMode>
 			</Iface>
 			<Iface>
 			   <Name>eth0</Name>