IPACM: add support for Ethernet Bridging
Add IPACM support for Ethernet Bridging in msmzirc.
Change-Id: I5cdc512542c23fd728d3593a85d9e1ad8d8b97bb
diff --git a/ipacm/src/IPACM_Config.cpp b/ipacm/src/IPACM_Config.cpp
index 4fa7a30..3fd3b55 100644
--- a/ipacm/src/IPACM_Config.cpp
+++ b/ipacm/src/IPACM_Config.cpp
@@ -76,6 +76,11 @@
memset(&ext_prop_v4, 0, sizeof(ext_prop_v4));
memset(&ext_prop_v6, 0, sizeof(ext_prop_v6));
+ memset(&rt_tbl_eth_bridge_usb_wlan_v4, 0, sizeof(rt_tbl_eth_bridge_usb_wlan_v4));
+ memset(&rt_tbl_eth_bridge_wlan_wlan_v4, 0, sizeof(rt_tbl_eth_bridge_wlan_wlan_v4));
+ memset(&rt_tbl_eth_bridge_usb_wlan_v6, 0, sizeof(rt_tbl_eth_bridge_usb_wlan_v6));
+ memset(&rt_tbl_eth_bridge_wlan_wlan_v6, 0, sizeof(rt_tbl_eth_bridge_wlan_wlan_v6));
+
qmap_id = ~0;
IPACMDBG_H(" create IPACM_Config constructor\n");
@@ -253,6 +258,18 @@
rt_tbl_lan2lan_v6.ip = IPA_IP_v6;
strncpy(rt_tbl_lan2lan_v6.name, V6_LAN_TO_LAN_ROUTE_TABLE_NAME, sizeof(rt_tbl_lan2lan_v6.name));
+ rt_tbl_eth_bridge_usb_wlan_v4.ip = IPA_IP_v4;
+ strncpy(rt_tbl_eth_bridge_usb_wlan_v4.name, ETH_BRIDGE_USB_WLAN_ROUTE_TABLE_NAME_V4, sizeof(rt_tbl_eth_bridge_usb_wlan_v4.name));
+
+ rt_tbl_eth_bridge_wlan_wlan_v4.ip = IPA_IP_v4;
+ strncpy(rt_tbl_eth_bridge_wlan_wlan_v4.name, ETH_BRIDGE_WLAN_WLAN_ROUTE_TABLE_NAME_V4, sizeof(rt_tbl_eth_bridge_wlan_wlan_v4.name));
+
+ rt_tbl_eth_bridge_usb_wlan_v6.ip = IPA_IP_v6;
+ strncpy(rt_tbl_eth_bridge_usb_wlan_v6.name, ETH_BRIDGE_USB_WLAN_ROUTE_TABLE_NAME_V6, sizeof(rt_tbl_eth_bridge_usb_wlan_v6.name));
+
+ rt_tbl_eth_bridge_wlan_wlan_v6.ip = IPA_IP_v6;
+ strncpy(rt_tbl_eth_bridge_wlan_wlan_v6.name, ETH_BRIDGE_WLAN_WLAN_ROUTE_TABLE_NAME_V6, sizeof(rt_tbl_eth_bridge_wlan_wlan_v6.name));
+
/* Construct IPACM ipa_client map to rm_resource table */
ipa_client_rm_map_tbl[IPA_CLIENT_WLAN1_PROD]= IPA_RM_RESOURCE_WLAN_PROD;
ipa_client_rm_map_tbl[IPA_CLIENT_USB_PROD]= IPA_RM_RESOURCE_USB_PROD;
diff --git a/ipacm/src/IPACM_Header.cpp b/ipacm/src/IPACM_Header.cpp
index 32486df..5e56a49 100644
--- a/ipacm/src/IPACM_Header.cpp
+++ b/ipacm/src/IPACM_Header.cpp
@@ -198,3 +198,34 @@
}
+bool IPACM_Header::AddHeaderProcCtx(struct ipa_ioc_add_hdr_proc_ctx* pHeader)
+{
+ int ret = 0;
+ //call the Driver ioctl to add header processing context
+ ret = ioctl(m_fd, IPA_IOC_ADD_HDR_PROC_CTX, pHeader);
+ return (ret != -1);
+}
+
+bool IPACM_Header::DeleteHeaderProcCtx(uint32_t hdl)
+{
+ int len, ret;
+ struct ipa_ioc_del_hdr_proc_ctx* pHeaderTable = NULL;
+
+ len = sizeof(struct ipa_ioc_del_hdr_proc_ctx) + sizeof(struct ipa_hdr_proc_ctx_del);
+ pHeaderTable = (struct ipa_ioc_del_hdr_proc_ctx*)malloc(len);
+ if(pHeaderTable == NULL)
+ {
+ IPACMERR("Failed to allocate buffer.\n");
+ return false;
+ }
+ memset(pHeaderTable, 0, len);
+
+ pHeaderTable->commit = 1;
+ pHeaderTable->num_hdls = 1;
+ pHeaderTable->hdl[0].hdl = hdl;
+
+ ret = ioctl(m_fd, IPA_IOC_DEL_HDR_PROC_CTX, pHeaderTable);
+ free(pHeaderTable);
+ return (ret != -1);
+}
+
diff --git a/ipacm/src/IPACM_IfaceManager.cpp b/ipacm/src/IPACM_IfaceManager.cpp
index 0c61833..335b64e 100644
--- a/ipacm/src/IPACM_IfaceManager.cpp
+++ b/ipacm/src/IPACM_IfaceManager.cpp
@@ -219,6 +219,12 @@
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6, lan);
IPACM_EvtDispatcher::registr(IPA_CFG_CHANGE_EVENT, lan); // register for IPA_CFG_CHANGE event
IPACM_EvtDispatcher::registr(IPA_PRIVATE_SUBNET_CHANGE_EVENT, lan); // register for IPA_PRIVATE_SUBNET_CHANGE_EVENT event
+#ifdef FEATURE_ETH_BRIDGE_LE
+ IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_WLAN_CLIENT_ADD_EVENT, lan);
+ IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_WLAN_CLIENT_DEL_EVENT, lan);
+ IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_HDR_PROC_CTX_SET_EVENT, lan);
+ IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_HDR_PROC_CTX_UNSET_EVENT, lan);
+#endif
IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, lan);
IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, lan);
IPACMDBG_H("ipa_LAN (%s):ipa_index (%d) instance open/registr ok\n", lan->dev_name, lan->ipa_if_num);
@@ -307,6 +313,12 @@
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN, wl);
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6, wl);
IPACM_EvtDispatcher::registr(IPA_PRIVATE_SUBNET_CHANGE_EVENT, wl); // register for IPA_PRIVATE_SUBNET_CHANGE_EVENT event
+#ifdef FEATURE_ETH_BRIDGE_LE
+ IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_USB_CLIENT_ADD_EVENT, wl);
+ IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_USB_CLIENT_DEL_EVENT, wl);
+ IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_HDR_PROC_CTX_SET_EVENT, wl);
+ IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_HDR_PROC_CTX_UNSET_EVENT, wl);
+#endif
IPACM_EvtDispatcher::registr(IPA_WLAN_LINK_DOWN_EVENT, wl);
IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, wl);
IPACMDBG_H("ipa_WLAN (%s):ipa_index (%d) instance open/registr ok\n", wl->dev_name, wl->ipa_if_num);
diff --git a/ipacm/src/IPACM_Lan.cpp b/ipacm/src/IPACM_Lan.cpp
index 19c6950..736a16e 100644
--- a/ipacm/src/IPACM_Lan.cpp
+++ b/ipacm/src/IPACM_Lan.cpp
@@ -55,6 +55,22 @@
bool IPACM_Lan::odu_up = false;
+ipa_hdr_l2_type IPACM_Lan::usb_hdr_type = IPA_HDR_L2_NONE;
+ipa_hdr_l2_type IPACM_Lan::wlan_hdr_type = IPA_HDR_L2_NONE;
+
+uint32_t IPACM_Lan::usb_hdr_template_hdl = 0;
+uint32_t IPACM_Lan::wlan_hdr_template_hdl = 0;
+
+hdr_proc_ctx_info IPACM_Lan::usb_to_wlan_hdr_proc_ctx;
+hdr_proc_ctx_info IPACM_Lan::wlan_to_usb_hdr_proc_ctx;
+hdr_proc_ctx_info IPACM_Lan::wlan_to_wlan_hdr_proc_ctx;
+
+eth_bridge_subnet_client_info IPACM_Lan::eth_bridge_wlan_client[IPA_LAN_TO_LAN_MAX_WLAN_CLIENT];
+eth_bridge_subnet_client_info IPACM_Lan::eth_bridge_usb_client[IPA_LAN_TO_LAN_MAX_USB_CLIENT];
+
+int IPACM_Lan::num_wlan_client = 0;
+int IPACM_Lan::num_usb_client = 0;
+
IPACM_Lan::IPACM_Lan(int iface_index) : IPACM_Iface(iface_index)
{
num_eth_client = 0;
@@ -88,6 +104,27 @@
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)
+ {
+ if(IPACM_Lan::usb_hdr_type != IPA_HDR_L2_NONE && tx_prop->tx[0].hdr_l2_type != IPACM_Lan::usb_hdr_type)
+ {
+ IPACMERR("The USB header format is not consistent! Now header format is %d.\n", tx_prop->tx[0].hdr_l2_type);
+ }
+ else
+ {
+ if(eth_bridge_get_hdr_template_hdl(&IPACM_Lan::usb_hdr_template_hdl) == IPACM_FAILURE)
+ {
+ IPACMERR("Failed to setup usb hdr template.\n");
+ }
+ else
+ {
+ IPACM_Lan::usb_hdr_type = tx_prop->tx[0].hdr_l2_type;
+ add_hdr_proc_ctx();
+ }
+ }
+ }
+#endif
/* ODU routing table initilization */
if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF)
{
@@ -116,6 +153,9 @@
memset(lan2lan_hdr_hdl_v4, 0, MAX_OFFLOAD_PAIR*sizeof(lan2lan_hdr_hdl));
memset(lan2lan_hdr_hdl_v6, 0, MAX_OFFLOAD_PAIR*sizeof(lan2lan_hdr_hdl));
+ memset(wlan_client_flt_rule_hdl_v4, 0, IPA_LAN_TO_LAN_MAX_WLAN_CLIENT * sizeof(lan2lan_flt_rule_hdl));
+ memset(wlan_client_flt_rule_hdl_v6, 0, IPA_LAN_TO_LAN_MAX_WLAN_CLIENT * sizeof(lan2lan_flt_rule_hdl));
+
is_active = true;
memset(tcp_ctl_flt_rule_hdl_v4, 0, NUM_TCP_CTL_FLT_RULE*sizeof(uint32_t));
memset(tcp_ctl_flt_rule_hdl_v6, 0, NUM_TCP_CTL_FLT_RULE*sizeof(uint32_t));
@@ -160,6 +200,40 @@
}
}
+ int i;
+ each_client_rt_rule_count_v4 = 0;
+ each_client_rt_rule_count_v6 = 0;
+ if(iface_query != NULL && tx_prop != NULL)
+ {
+ for(i=0; i<iface_query->num_tx_props; i++)
+ {
+ if(tx_prop->tx[i].ip == IPA_IP_v4)
+ {
+ each_client_rt_rule_count_v4++;
+ }
+ else
+ {
+ each_client_rt_rule_count_v6++;
+ }
+ }
+ }
+ IPACMDBG_H("Need to add %d IPv4 and %d IPv6 routing rules for eth bridge for each client.\n", each_client_rt_rule_count_v4, each_client_rt_rule_count_v6);
+
+ memset(eth_bridge_wlan_client_flt_info, 0, IPA_LAN_TO_LAN_MAX_WLAN_CLIENT * sizeof(eth_bridge_client_flt_info));
+ wlan_client_flt_info_count = 0;
+ eth_bridge_usb_client_rt_info_v4 = NULL;
+ eth_bridge_usb_client_rt_info_v6 = NULL;
+#ifdef FEATURE_ETH_BRIDGE_LE
+ if(tx_prop != NULL)
+ {
+ client_rt_info_size_v4 = sizeof(eth_bridge_client_rt_info) + each_client_rt_rule_count_v4 * sizeof(uint32_t);
+ eth_bridge_usb_client_rt_info_v4 = (eth_bridge_client_rt_info*)calloc(IPA_LAN_TO_LAN_MAX_USB_CLIENT, client_rt_info_size_v4);
+ client_rt_info_size_v6 = sizeof(eth_bridge_client_rt_info) + each_client_rt_rule_count_v6 * sizeof(uint32_t);
+ eth_bridge_usb_client_rt_info_v6 = (eth_bridge_client_rt_info*)calloc(IPA_LAN_TO_LAN_MAX_USB_CLIENT, client_rt_info_size_v6);
+ }
+#endif
+ usb_client_rt_info_count_v4 = 0;
+ usb_client_rt_info_count_v6 = 0;
return;
}
@@ -526,6 +600,15 @@
/* Add NAT rules after ipv4 RT rules are set */
CtList->HandleNeighIpAddrAddEvt(data);
}
+#ifdef FEATURE_ETH_BRIDGE_LE
+ if(IPACM_Lan::wlan_to_usb_hdr_proc_ctx.valid == true)
+ {
+ eth_bridge_add_usb_client_rt_rule(data->mac_addr, IPA_IP_v4);
+ eth_bridge_add_usb_client_rt_rule(data->mac_addr, IPA_IP_v6);
+ }
+ eth_bridge_post_lan_client_event(data->mac_addr, IPA_ETH_BRIDGE_USB_CLIENT_ADD_EVENT);
+ eth_bridge_add_usb_client(data->mac_addr);
+#endif
return;
}
}
@@ -559,6 +642,93 @@
handle_software_routing_disable();
break;
+ case IPA_ETH_BRIDGE_WLAN_CLIENT_ADD_EVENT:
+ {
+ IPACMDBG_H("Received IPA_ETH_BRIDGE_WLAN_CLIENT_ADD_EVENT event.\n");
+ ipacm_event_data_mac* mac = (ipacm_event_data_mac*)param;
+ if(mac != NULL)
+ {
+ if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
+ {
+ eth_bridge_add_wlan_client_flt_rule(mac->mac_addr, IPA_IP_v4);
+ }
+ if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
+ {
+ eth_bridge_add_wlan_client_flt_rule(mac->mac_addr, IPA_IP_v6);
+ }
+ }
+ else
+ {
+ IPACMERR("Event MAC is empty.\n");
+ }
+ }
+ break;
+
+ case IPA_ETH_BRIDGE_WLAN_CLIENT_DEL_EVENT:
+ {
+ IPACMDBG_H("Received IPA_ETH_BRIDGE_WLAN_CLIENT_DEL_EVENT event.\n");
+ ipacm_event_data_mac* mac = (ipacm_event_data_mac*)param;
+ if(mac != NULL)
+ {
+ if(eth_bridge_del_wlan_client_flt_rule(mac->mac_addr) == IPACM_FAILURE)
+ {
+ IPACMDBG_H("Failed to delete wlan client MAC based flt rule.\n");
+ }
+ }
+ else
+ {
+ IPACMERR("Event MAC is empty.\n");
+ }
+ }
+ break;
+
+ case IPA_ETH_BRIDGE_HDR_PROC_CTX_SET_EVENT:
+ {
+ IPACMDBG_H("Received IPA_ETH_BRIDGE_HDR_PROC_CTX_SET_EVENT event.\n");
+ int i;
+ ipacm_event_data_fid* fid = (ipacm_event_data_fid*)param;
+ if(fid == NULL)
+ {
+ IPACMERR("Event data is empty.\n");
+ return;
+ }
+ if(fid->if_index == ipa_if_num)
+ {
+ IPACMDBG_H("The event was sent by the same interface, ignore.\n");
+ return;
+ }
+
+ for(i=0; i<IPACM_Lan::num_usb_client; i++)
+ {
+ eth_bridge_add_usb_client_rt_rule(IPACM_Lan::eth_bridge_usb_client[i].mac, IPA_IP_v4);
+ eth_bridge_add_usb_client_rt_rule(IPACM_Lan::eth_bridge_usb_client[i].mac, IPA_IP_v6);
+ }
+ }
+ break;
+
+ case IPA_ETH_BRIDGE_HDR_PROC_CTX_UNSET_EVENT:
+ {
+ IPACMDBG_H("Received IPA_ETH_BRIDGE_HDR_PROC_CTX_UNSET_EVENT event.\n");
+ int i;
+ ipacm_event_data_fid* fid = (ipacm_event_data_fid*)param;
+ if(fid == NULL)
+ {
+ IPACMERR("Event data is empty.\n");
+ return;
+ }
+ if(fid->if_index == ipa_if_num)
+ {
+ IPACMDBG_H("The event was sent by the same interface, ignore.\n");
+ return;
+ }
+
+ for(i=0; i<IPACM_Lan::num_usb_client; i++)
+ {
+ eth_bridge_del_usb_client_rt_rule(IPACM_Lan::eth_bridge_usb_client[i].mac);
+ }
+ }
+ break;
+
default:
break;
}
@@ -578,18 +748,20 @@
IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
return IPACM_FAILURE;
}
-
+#ifdef FEATURE_ETH_BRIDGE_LE
+ flt_rule_count_v4 = IPV4_DEFAULT_FILTERTING_RULES + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPACM_Iface::ipacmcfg->ipa_num_private_subnet;
+#else
#ifdef CT_OPT
flt_rule_count_v4 = IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR
- + NUM_TCP_CTL_FLT_RULE + IPACM_Iface::ipacmcfg->ipa_num_private_subnet;
+ + NUM_TCP_CTL_FLT_RULE + IPACM_Iface::ipacmcfg->ipa_num_private_subnet;
#else
flt_rule_count_v4 = IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR
- + IPACM_Iface::ipacmcfg->ipa_num_private_subnet;
+ + IPACM_Iface::ipacmcfg->ipa_num_private_subnet;
#endif
-
#ifdef FEATURE_IPA_ANDROID
flt_rule_count_v4 = flt_rule_count_v4 - IPACM_Iface::ipacmcfg->ipa_num_private_subnet + IPA_MAX_PRIVATE_SUBNET_ENTRIES;
#endif
+#endif
if(is_sta_mode == false)
{
@@ -704,11 +876,20 @@
dft_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl;
IPACMDBG_H("ipv4 iface rt-rule hdl1=0x%x\n", dft_rt_rule_hdl[0]);
/* 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_usb_client_flt_rule(data->iptype);
+ eth_bridge_install_cache_wlan_client_flt_rule(data->iptype);
+ eth_bridge_install_cache_usb_client_flt_rule(data->iptype);
+#else
#ifdef CT_OPT
install_tcp_ctl_flt_rule(IPA_IP_v4);
#endif
init_fl_rule(data->iptype);
add_dummy_lan2lan_flt_rule(data->iptype);
+#endif
}
else
{
@@ -793,12 +974,21 @@
if (num_dft_rt_v6 == 0)
{
+ /* 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_usb_client_flt_rule(data->iptype);
+ eth_bridge_install_cache_wlan_client_flt_rule(data->iptype);
+ eth_bridge_install_cache_usb_client_flt_rule(data->iptype);
+ init_fl_rule(data->iptype);
+#else
#ifdef CT_OPT
install_tcp_ctl_flt_rule(IPA_IP_v6);
#endif
add_dummy_lan2lan_flt_rule(data->iptype);
- /* initial multicast/broadcast/fragment filter rule */
init_fl_rule(data->iptype);
+#endif
}
num_dft_rt_v6++;
IPACMDBG_H("number of default route rules %d\n", num_dft_rt_v6);
@@ -2099,6 +2289,7 @@
{
int i;
int res = IPACM_SUCCESS;
+ uint32_t temp_eth_bridge_flt_rule[IPA_LAN_TO_LAN_MAX_WLAN_CLIENT];
if (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF)
{
@@ -2138,6 +2329,12 @@
}
IPACMDBG_H("lan handle_down_evt\n ");
+#ifdef FEATURE_ETH_BRIDGE_LE
+ IPACM_Lan::usb_hdr_type = IPA_HDR_L2_NONE;
+ IPACM_Lan::usb_hdr_template_hdl = 0;
+ del_hdr_proc_ctx();
+#endif
+
/* delete wan filter rule */
if (IPACM_Wan::isWanUP() && rx_prop != NULL)
{
@@ -2160,12 +2357,25 @@
res = IPACM_FAILURE;
goto fail;
}
+#ifdef FEATURE_ETH_BRIDGE_LE
+ for(i=0; i<IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; i++)
+ {
+ temp_eth_bridge_flt_rule[i] = wlan_client_flt_rule_hdl_v4[i].rule_hdl;
+ }
+ if (m_filtering.DeleteFilteringHdls(temp_eth_bridge_flt_rule, IPA_IP_v4, IPA_LAN_TO_LAN_MAX_WLAN_CLIENT) == false)
+ {
+ IPACMERR("Error Deleting Filtering Rule, aborting...\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+#endif
if(m_filtering.DeleteFilteringHdls(ipv6_icmp_flt_rule_hdl, IPA_IP_v6, NUM_IPV6_ICMP_FLT_RULE) == false)
{
IPACMERR("Error Deleting ICMPv6 Filtering Rule, aborting...\n");
res = IPACM_FAILURE;
goto fail;
}
+#ifndef FEATURE_ETH_BRIDGE_LE
#ifdef CT_OPT
if (m_filtering.DeleteFilteringHdls(tcp_ctl_flt_rule_hdl_v4, IPA_IP_v4, NUM_TCP_CTL_FLT_RULE) == false)
{
@@ -2184,6 +2394,7 @@
}
}
IPACMDBG_H("Deleted lan2lan IPv4 flt rules.\n");
+#endif
/* free private-subnet ipv4 filter rules */
if (IPACM_Iface::ipacmcfg->ipa_num_private_subnet > IPA_PRIV_SUBNET_FILTER_RULE_HANDLES)
@@ -2221,6 +2432,19 @@
res = IPACM_FAILURE;
goto fail;
}
+#ifdef FEATURE_ETH_BRIDGE_LE
+ for(i=0; i<IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; i++)
+ {
+ temp_eth_bridge_flt_rule[i] = wlan_client_flt_rule_hdl_v6[i].rule_hdl;
+ }
+ if (m_filtering.DeleteFilteringHdls(temp_eth_bridge_flt_rule, IPA_IP_v6, IPA_LAN_TO_LAN_MAX_WLAN_CLIENT) == false)
+ {
+ IPACMERR("Error Deleting Filtering Rule, aborting...\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+#endif
+#ifndef FEATURE_ETH_BRIDGE_LE
#ifdef CT_OPT
if (m_filtering.DeleteFilteringHdls(tcp_ctl_flt_rule_hdl_v6, IPA_IP_v6, NUM_TCP_CTL_FLT_RULE) == false)
{
@@ -2239,6 +2463,7 @@
}
}
IPACMDBG_H("Deleted lan2lan IPv6 flt rules.\n");
+#endif
}
IPACMDBG_H("Finished delete default iface ipv6 filtering rules \n ");
@@ -2275,6 +2500,12 @@
IPACMDBG_H("left %d eth clients need to be deleted \n ", num_eth_client);
for (i = 0; i < num_eth_client; i++)
{
+#ifdef FEATURE_ETH_BRIDGE_LE
+ eth_bridge_del_usb_client_rt_rule(get_client_memptr(eth_client, i)->mac);
+ eth_bridge_post_lan_client_event(get_client_memptr(eth_client, i)->mac, IPA_ETH_BRIDGE_USB_CLIENT_DEL_EVENT);
+ eth_bridge_del_usb_client(get_client_memptr(eth_client, i)->mac);
+#endif
+
/* First reset nat rules and then route rules */
if(get_client_memptr(eth_client, i)->ipv4_set == true)
{
@@ -2382,7 +2613,16 @@
{
free(iface_query);
}
-
+#ifdef FEATURE_ETH_BRIDGE_LE
+ if(eth_bridge_usb_client_rt_info_v4 != NULL)
+ {
+ free(eth_bridge_usb_client_rt_info_v4);
+ }
+ if(eth_bridge_usb_client_rt_info_v6 != NULL)
+ {
+ free(eth_bridge_usb_client_rt_info_v6);
+ }
+#endif
is_active = false;
post_del_self_evt();
@@ -2545,12 +2785,15 @@
IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
return IPACM_FAILURE;
}
-
+#ifdef FEATURE_ETH_BRIDGE_LE
+ flt_rule_count_v6 = IPV6_DEFAULT_FILTERTING_RULES + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + NUM_IPV6_ICMP_FLT_RULE;
+#else
#ifdef CT_OPT
flt_rule_count_v6 = IPV6_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + NUM_IPV6_ICMP_FLT_RULE;
#else
flt_rule_count_v6 = IPV6_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + NUM_IPV6_ICMP_FLT_RULE;
#endif
+#endif
if(m_filtering.DeleteFilteringHdls(ipv6_prefix_flt_rule_hdl, IPA_IP_v6, NUM_IPV6_PREFIX_FLT_RULE) == false)
{
@@ -3925,7 +4168,7 @@
int IPACM_Lan::handle_private_subnet_android(ipa_ip_type iptype)
{
- int i, len, res = IPACM_SUCCESS, offset;
+ int i, len, res = IPACM_SUCCESS;
struct ipa_flt_rule_mdfy flt_rule;
struct ipa_ioc_mdfy_flt_rule* pFilteringTable;
@@ -4164,3 +4407,1011 @@
return res;
}
+
+int IPACM_Lan::eth_bridge_handle_dummy_wlan_client_flt_rule(ipa_ip_type iptype)
+{
+ if(rx_prop == NULL)
+ {
+ IPACMDBG_H("There is no rx_prop for iface %s, not able to add dummy wlan client specific filtering rule.\n", dev_name);
+ return 0;
+ }
+
+ int i, len, res = IPACM_SUCCESS;
+ struct ipa_flt_rule_add flt_rule;
+ ipa_ioc_add_flt_rule* pFilteringTable;
+
+ len = sizeof(struct ipa_ioc_add_flt_rule) + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT * sizeof(struct ipa_flt_rule_add);
+
+ pFilteringTable = (struct ipa_ioc_add_flt_rule *)malloc(len);
+ if (pFilteringTable == NULL)
+ {
+ IPACMERR("Error allocate flt table memory...\n");
+ return IPACM_FAILURE;
+ }
+ memset(pFilteringTable, 0, len);
+
+ pFilteringTable->commit = 1;
+ pFilteringTable->ep = rx_prop->rx[0].src_pipe;
+ pFilteringTable->global = false;
+ pFilteringTable->ip = iptype;
+ pFilteringTable->num_rules = IPA_LAN_TO_LAN_MAX_WLAN_CLIENT;
+
+ memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_add));
+
+ flt_rule.rule.retain_hdr = 0;
+ flt_rule.at_rear = true;
+ flt_rule.flt_rule_hdl = -1;
+ flt_rule.status = -1;
+ flt_rule.rule.action = IPA_PASS_TO_EXCEPTION;
+
+ memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib,
+ sizeof(flt_rule.rule.attrib));
+
+ if(iptype == IPA_IP_v4)
+ {
+ flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR;
+ flt_rule.rule.attrib.u.v4.src_addr_mask = ~0;
+ flt_rule.rule.attrib.u.v4.src_addr = ~0;
+ flt_rule.rule.attrib.u.v4.dst_addr_mask = ~0;
+ flt_rule.rule.attrib.u.v4.dst_addr = ~0;
+
+ for(i=0; i<IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; i++)
+ {
+ memcpy(&(pFilteringTable->rules[i]), &flt_rule, sizeof(struct ipa_flt_rule_add));
+ }
+
+ if (false == m_filtering.AddFilteringRule(pFilteringTable))
+ {
+ IPACMERR("Error adding dummy lan2lan v4 flt rule\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ else
+ {
+ flt_rule_count_v4 += IPA_LAN_TO_LAN_MAX_WLAN_CLIENT;
+ /* copy filter rule hdls */
+ for (int i = 0; i < IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; i++)
+ {
+ if (pFilteringTable->rules[i].status == 0)
+ {
+ wlan_client_flt_rule_hdl_v4[i].rule_hdl = pFilteringTable->rules[i].flt_rule_hdl;
+ wlan_client_flt_rule_hdl_v4[i].valid = true;
+ IPACMDBG_H("Wlan client v4 flt rule %d hdl:0x%x\n", i, wlan_client_flt_rule_hdl_v4[i].rule_hdl);
+ }
+ else
+ {
+ IPACMERR("Failed adding wlan client v4 flt rule %d\n", i);
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ }
+ }
+ }
+ else if(iptype == IPA_IP_v6)
+ {
+ flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR;
+ flt_rule.rule.attrib.u.v6.src_addr_mask[0] = ~0;
+ flt_rule.rule.attrib.u.v6.src_addr_mask[1] = ~0;
+ flt_rule.rule.attrib.u.v6.src_addr_mask[2] = ~0;
+ flt_rule.rule.attrib.u.v6.src_addr_mask[3] = ~0;
+ flt_rule.rule.attrib.u.v6.src_addr[0] = ~0;
+ flt_rule.rule.attrib.u.v6.src_addr[1] = ~0;
+ flt_rule.rule.attrib.u.v6.src_addr[2] = ~0;
+ flt_rule.rule.attrib.u.v6.src_addr[3] = ~0;
+ flt_rule.rule.attrib.u.v6.dst_addr_mask[0] = ~0;
+ flt_rule.rule.attrib.u.v6.dst_addr_mask[1] = ~0;
+ flt_rule.rule.attrib.u.v6.dst_addr_mask[2] = ~0;
+ flt_rule.rule.attrib.u.v6.dst_addr_mask[3] = ~0;
+ flt_rule.rule.attrib.u.v6.dst_addr[0] = ~0;
+ flt_rule.rule.attrib.u.v6.dst_addr[1] = ~0;
+ flt_rule.rule.attrib.u.v6.dst_addr[2] = ~0;
+ flt_rule.rule.attrib.u.v6.dst_addr[3] = ~0;
+
+ for(i=0; i<IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; i++)
+ {
+ memcpy(&(pFilteringTable->rules[i]), &flt_rule, sizeof(struct ipa_flt_rule_add));
+ }
+
+ if (false == m_filtering.AddFilteringRule(pFilteringTable))
+ {
+ IPACMERR("Error adding dummy lan2lan v6 flt rule\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ else
+ {
+ flt_rule_count_v6 += IPA_LAN_TO_LAN_MAX_WLAN_CLIENT;
+ /* copy filter rule hdls */
+ for (int i = 0; i < IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; i++)
+ {
+ if (pFilteringTable->rules[i].status == 0)
+ {
+ wlan_client_flt_rule_hdl_v6[i].rule_hdl = pFilteringTable->rules[i].flt_rule_hdl;
+ wlan_client_flt_rule_hdl_v6[i].valid = true;
+ IPACMDBG_H("Wlan client v6 flt rule %d hdl:0x%x\n", i, wlan_client_flt_rule_hdl_v6[i].rule_hdl);
+ }
+ else
+ {
+ IPACMERR("Failed adding wlan client v6 flt rule %d\n", i);
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ }
+ }
+ }
+ else
+ {
+ IPACMERR("IP type is not expected.\n");
+ goto fail;
+ }
+
+fail:
+ free(pFilteringTable);
+ return res;
+}
+
+int IPACM_Lan::eth_bridge_add_wlan_guest_ap_flt_rule(ipa_ip_type iptype)
+{
+ IPACMDBG_H("No need to add WLAN guest AP flt rule on USB pipe.\n");
+ return IPACM_SUCCESS;
+}
+
+int IPACM_Lan::eth_bridge_handle_dummy_usb_client_flt_rule(ipa_ip_type iptype)
+{
+ IPACMDBG_H("No need to add USB client specific flt rule on USB pipe.\n");
+ return IPACM_SUCCESS;
+}
+
+int IPACM_Lan::eth_bridge_post_lan_client_event(uint8_t* mac_addr, ipa_cm_event_id evt)
+{
+ if(mac_addr == NULL)
+ {
+ IPACMERR("Event mac is empty.\n");
+ return IPACM_FAILURE;
+ }
+
+ ipacm_cmd_q_data evt_data;
+ memset(&evt_data, 0, sizeof(evt_data));
+
+ ipacm_event_data_mac* mac;
+ mac = (ipacm_event_data_mac*)malloc(sizeof(ipacm_event_data_mac));
+ if(mac == NULL)
+ {
+ IPACMERR("Unable to allocate memory.\n");
+ return IPACM_FAILURE;
+ }
+ memset(mac, 0, sizeof(ipacm_event_data_mac));
+ memcpy(mac->mac_addr, mac_addr, 6 * sizeof(uint8_t));
+
+ evt_data.event = evt;
+ evt_data.evt_data = (void*)mac;
+ IPACMDBG_H("Posting event: %d\n", evt);
+ IPACM_EvtDispatcher::PostEvt(&evt_data);
+ return IPACM_SUCCESS;
+}
+
+int IPACM_Lan::eth_bridge_add_wlan_client_flt_rule(uint8_t* mac, ipa_ip_type iptype)
+{
+ int i, len, res = IPACM_SUCCESS, client_position;
+ struct ipa_flt_rule_mdfy flt_rule;
+ struct ipa_ioc_mdfy_flt_rule* pFilteringTable = NULL;
+ bool client_is_found = false;
+
+ 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;
+ }
+ if(IPACM_Lan::usb_to_wlan_hdr_proc_ctx.valid == false)
+ {
+ IPACMDBG_H("USB to WLAN hdr proc ctx has not been set, don't add client specific flt rule.\n");
+ return IPACM_FAILURE;
+ }
+
+ for(i=0; i<wlan_client_flt_info_count; i++)
+ {
+ if(memcmp(eth_bridge_wlan_client_flt_info[i].mac, mac, sizeof(eth_bridge_wlan_client_flt_info[i].mac)) == 0)
+ {
+ client_is_found = true;
+ client_position = i;
+ if( (iptype == IPA_IP_v4 && eth_bridge_wlan_client_flt_info[i].flt_rule_set_v4 == true)
+ || (iptype == IPA_IP_v6 && eth_bridge_wlan_client_flt_info[i].flt_rule_set_v6 == true))
+ {
+ IPACMDBG_H("Flt rule for iptype %d has been set.\n", iptype);
+ return IPACM_SUCCESS;
+ }
+ break;
+ }
+ }
+
+ if(client_is_found == false && wlan_client_flt_info_count == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT)
+ {
+ IPACMDBG_H("The wlan client flt table is already full.\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);
+
+ 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]);
+
+ /* add mac based rule*/
+ pFilteringTable->commit = 1;
+ pFilteringTable->ip = iptype;
+ pFilteringTable->num_rules = 1;
+
+ 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;
+
+ /* point to USB-WLAN routing table */
+ if(iptype == IPA_IP_v4)
+ {
+ if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_usb_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_usb_wlan_v4.hdl;
+ IPACMDBG_H("USB->WLAN filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_usb_wlan_v4.name);
+ }
+ else
+ {
+ if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_usb_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_usb_wlan_v6.hdl;
+ IPACMDBG_H("USB->WLAN filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_usb_wlan_v6.name);
+ }
+
+ memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib));
+ if(IPACM_Lan::usb_hdr_type == IPA_HDR_L2_ETHERNET_II)
+ {
+ flt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II;
+ }
+ else if(IPACM_Lan::usb_hdr_type == IPA_HDR_L2_802_3)
+ {
+ flt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3;
+ }
+ else
+ {
+ IPACMERR("USB 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(iptype == IPA_IP_v4)
+ {
+ for(i=0; i<IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; i++)
+ {
+ if(wlan_client_flt_rule_hdl_v4[i].valid == true)
+ {
+ flt_rule.rule_hdl = wlan_client_flt_rule_hdl_v4[i].rule_hdl;
+ wlan_client_flt_rule_hdl_v4[i].valid = false;
+ break;
+ }
+ }
+ if(i == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT)
+ {
+ IPACMDBG_H("Cannot find a valid flt rule hdl.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ }
+ else
+ {
+ for(i=0; i<IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; i++)
+ {
+ if(wlan_client_flt_rule_hdl_v6[i].valid == true)
+ {
+ flt_rule.rule_hdl = wlan_client_flt_rule_hdl_v6[i].rule_hdl;
+ wlan_client_flt_rule_hdl_v6[i].valid = false;
+ break;
+ }
+ }
+ if(i == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT)
+ {
+ IPACMDBG_H("Cannot find a valid flt rule hdl.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ }
+
+ memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy));
+ if (false == m_filtering.ModifyFilteringRule(pFilteringTable))
+ {
+ IPACMERR("Failed to add wlan client filtering rules.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ if(client_is_found == false)
+ {
+ client_position = wlan_client_flt_info_count;
+ wlan_client_flt_info_count++;
+ }
+
+ memcpy(eth_bridge_wlan_client_flt_info[client_position].mac, mac, sizeof(eth_bridge_wlan_client_flt_info[client_position].mac));
+ if(iptype == IPA_IP_v4)
+ {
+ eth_bridge_wlan_client_flt_info[client_position].flt_rule_set_v4 = true;
+ eth_bridge_wlan_client_flt_info[client_position].flt_rule_hdl_v4 = wlan_client_flt_rule_hdl_v4[i].rule_hdl;
+ }
+ else
+ {
+ eth_bridge_wlan_client_flt_info[client_position].flt_rule_set_v6 = true;
+ eth_bridge_wlan_client_flt_info[client_position].flt_rule_hdl_v6 = wlan_client_flt_rule_hdl_v6[i].rule_hdl;
+ }
+
+fail:
+ if(pFilteringTable == NULL)
+ {
+ free(pFilteringTable);
+ }
+ return res;
+}
+
+int IPACM_Lan::eth_bridge_del_wlan_client_flt_rule(uint8_t* mac)
+{
+ if(mac == NULL)
+ {
+ IPACMERR("Client MAC address is empty.\n");
+ 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, j, res = IPACM_SUCCESS;
+ for(i=0; i<wlan_client_flt_info_count; i++)
+ {
+ if(memcmp(eth_bridge_wlan_client_flt_info[i].mac, mac, sizeof(eth_bridge_wlan_client_flt_info[i].mac)) == 0)
+ {
+ break;
+ }
+ }
+
+ if(i == wlan_client_flt_info_count)
+ {
+ IPACMERR("Do not find the wlan client.\n");
+ return IPACM_FAILURE;
+ }
+
+ if(eth_bridge_wlan_client_flt_info[i].flt_rule_set_v4 == true)
+ {
+ if(reset_to_dummy_flt_rule(IPA_IP_v4, eth_bridge_wlan_client_flt_info[i].flt_rule_hdl_v4) == IPACM_SUCCESS)
+ {
+ for(j=0; j<IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; j++)
+ {
+ if(wlan_client_flt_rule_hdl_v4[j].rule_hdl == eth_bridge_wlan_client_flt_info[i].flt_rule_hdl_v4)
+ {
+ wlan_client_flt_rule_hdl_v4[j].valid = true;
+ break;
+ }
+ }
+ if(j == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT)
+ {
+ IPACMERR("Not finding the rule handle in handle pool.\n");
+ return IPACM_FAILURE;
+ }
+ }
+ else
+ {
+ IPACMERR("Failed to delete the wlan client specific flt rule.\n");
+ return IPACM_FAILURE;
+ }
+ }
+ if(eth_bridge_wlan_client_flt_info[i].flt_rule_set_v6 == true)
+ {
+ if(reset_to_dummy_flt_rule(IPA_IP_v6, eth_bridge_wlan_client_flt_info[i].flt_rule_hdl_v6) == IPACM_SUCCESS)
+ {
+ for(j=0; j<IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; j++)
+ {
+ if(wlan_client_flt_rule_hdl_v6[j].rule_hdl == eth_bridge_wlan_client_flt_info[i].flt_rule_hdl_v6)
+ {
+ wlan_client_flt_rule_hdl_v6[j].valid = true;
+ break;
+ }
+ }
+ if(j == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT)
+ {
+ IPACMERR("Not finding the rule handle in handle pool.\n");
+ return IPACM_FAILURE;
+ }
+ }
+ else
+ {
+ IPACMERR("Failed to delete the wlan client specific flt rule.\n");
+ return IPACM_FAILURE;
+ }
+ }
+
+ for(j=i+1; j<wlan_client_flt_info_count; j++)
+ {
+ memcpy(&(eth_bridge_wlan_client_flt_info[j-1]), &(eth_bridge_wlan_client_flt_info[j]), sizeof(eth_bridge_client_flt_info));
+ }
+ memset(&(eth_bridge_wlan_client_flt_info[wlan_client_flt_info_count-1]), 0, sizeof(eth_bridge_client_flt_info));
+ wlan_client_flt_info_count--;
+
+ return res;
+}
+
+int IPACM_Lan::add_hdr_proc_ctx()
+{
+ int len, res = IPACM_SUCCESS;
+ struct ipa_ioc_add_hdr_proc_ctx* pHeaderProcTable = NULL;
+
+ len = sizeof(struct ipa_ioc_add_hdr_proc_ctx) + sizeof(struct ipa_hdr_proc_ctx_add);
+ pHeaderProcTable = (ipa_ioc_add_hdr_proc_ctx*)malloc(len);
+ if(pHeaderProcTable == NULL)
+ {
+ IPACMERR("Cannot allocate header processing table.\n");
+ return IPACM_FAILURE;
+ }
+
+ if(IPACM_Lan::wlan_hdr_type != IPA_HDR_L2_NONE)
+ {
+ if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == WLAN_IF)
+ {
+ if(IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.valid == false)
+ {
+ memset(pHeaderProcTable, 0, len);
+ pHeaderProcTable->commit = 1;
+ pHeaderProcTable->num_proc_ctxs = 1;
+ pHeaderProcTable->proc_ctx[0].type = get_hdr_proc_type(IPACM_Lan::wlan_hdr_type, IPACM_Lan::wlan_hdr_type);
+ pHeaderProcTable->proc_ctx[0].hdr_hdl = IPACM_Lan::wlan_hdr_template_hdl;
+ if (m_header.AddHeaderProcCtx(pHeaderProcTable) == false)
+ {
+ IPACMERR("Adding WLAN to WLAN hdr proc ctx failed with status: %d\n", pHeaderProcTable->proc_ctx[0].status);
+ res = IPACM_FAILURE;
+ }
+ else
+ {
+ IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.proc_ctx_hdl = pHeaderProcTable->proc_ctx[0].proc_ctx_hdl;
+ IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.valid = true;
+ }
+ }
+ }
+
+ if(IPACM_Lan::usb_hdr_type != IPA_HDR_L2_NONE)
+ {
+ if(IPACM_Lan::usb_to_wlan_hdr_proc_ctx.valid == false)
+ {
+ memset(pHeaderProcTable, 0, len);
+ pHeaderProcTable->commit = 1;
+ pHeaderProcTable->num_proc_ctxs = 1;
+ pHeaderProcTable->proc_ctx[0].type = get_hdr_proc_type(IPACM_Lan::usb_hdr_type, IPACM_Lan::wlan_hdr_type);
+ pHeaderProcTable->proc_ctx[0].hdr_hdl = IPACM_Lan::wlan_hdr_template_hdl;
+ if (m_header.AddHeaderProcCtx(pHeaderProcTable) == false)
+ {
+ IPACMERR("Adding USB to WLAN hdr proc ctx failed with status: %d\n", pHeaderProcTable->proc_ctx[0].status);
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ else
+ {
+ IPACM_Lan::usb_to_wlan_hdr_proc_ctx.proc_ctx_hdl = pHeaderProcTable->proc_ctx[0].proc_ctx_hdl;
+ IPACM_Lan::usb_to_wlan_hdr_proc_ctx.valid = true;
+ }
+
+ ipacm_cmd_q_data evt_data;
+ memset(&evt_data, 0, sizeof(ipacm_cmd_q_data));
+
+ ipacm_event_data_fid* fid;
+ fid = (ipacm_event_data_fid*)malloc(sizeof(ipacm_event_data_fid));
+ if(fid == NULL)
+ {
+ IPACMERR("Unable to allocate memory.\n");
+ return IPACM_FAILURE;
+ }
+ memset(fid, 0, sizeof(ipacm_event_data_fid));
+ fid->if_index = ipa_if_num;
+
+ evt_data.evt_data = fid;
+ evt_data.event = IPA_ETH_BRIDGE_HDR_PROC_CTX_SET_EVENT;
+ IPACMDBG_H("Posting event IPA_ETH_BRIDGE_HDR_PROC_CTX_SET_EVENT\n");
+ IPACM_EvtDispatcher::PostEvt(&evt_data);
+ }
+
+ if(IPACM_Lan::wlan_to_usb_hdr_proc_ctx.valid == false)
+ {
+ memset(pHeaderProcTable, 0, len);
+ pHeaderProcTable->commit = 1;
+ pHeaderProcTable->num_proc_ctxs = 1;
+ pHeaderProcTable->proc_ctx[0].type = get_hdr_proc_type(IPACM_Lan::wlan_hdr_type, IPACM_Lan::usb_hdr_type);
+ pHeaderProcTable->proc_ctx[0].hdr_hdl = IPACM_Lan::usb_hdr_template_hdl;
+ if (m_header.AddHeaderProcCtx(pHeaderProcTable) == false)
+ {
+ IPACMERR("Adding WLAN to USB hdr proc ctx failed with status: %d\n", pHeaderProcTable->proc_ctx[0].status);
+ m_header.DeleteHeaderProcCtx(IPACM_Lan::usb_to_wlan_hdr_proc_ctx.proc_ctx_hdl);
+ IPACM_Lan::usb_to_wlan_hdr_proc_ctx.valid = false;
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ else
+ {
+ IPACM_Lan::wlan_to_usb_hdr_proc_ctx.proc_ctx_hdl = pHeaderProcTable->proc_ctx[0].proc_ctx_hdl;
+ IPACM_Lan::wlan_to_usb_hdr_proc_ctx.valid = true;
+ }
+ }
+ }
+ }
+ else
+ {
+ IPACMDBG_H("Not adding header processing context.\n");
+ }
+
+fail:
+ free(pHeaderProcTable);
+ return res;
+}
+
+ipa_hdr_proc_type IPACM_Lan::get_hdr_proc_type(ipa_hdr_l2_type t1, ipa_hdr_l2_type t2)
+{
+ if(t1 == IPA_HDR_L2_ETHERNET_II)
+ {
+ if(t2 == IPA_HDR_L2_ETHERNET_II)
+ {
+ return IPA_HDR_PROC_ETHII_TO_ETHII;
+ }
+ if(t2 == IPA_HDR_L2_802_3)
+ {
+ return IPA_HDR_PROC_ETHII_TO_802_3;
+ }
+ }
+
+ if(t1 == IPA_HDR_L2_802_3)
+ {
+ if(t2 == IPA_HDR_L2_ETHERNET_II)
+ {
+ return IPA_HDR_PROC_802_3_TO_ETHII;
+ }
+ if(t2 == IPA_HDR_L2_802_3)
+ {
+ return IPA_HDR_PROC_802_3_TO_802_3;
+ }
+ }
+
+ return IPA_HDR_PROC_NONE;
+}
+
+int IPACM_Lan::eth_bridge_install_cache_wlan_client_flt_rule(ipa_ip_type iptype)
+{
+ int i;
+
+ IPACMDBG_H("There are %d wlan clients cached.\n",IPACM_Lan::num_wlan_client);
+ for(i=0; i<IPACM_Lan::num_wlan_client; i++)
+ {
+ eth_bridge_add_wlan_client_flt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac, iptype);
+ }
+ return IPACM_SUCCESS;
+}
+
+int IPACM_Lan::eth_bridge_install_cache_usb_client_flt_rule(ipa_ip_type iptype)
+{
+ IPACMDBG_H("No need to install usb client specific flt rules on usb pipe.\n");
+ return IPACM_SUCCESS;
+}
+
+int IPACM_Lan::eth_bridge_add_usb_client_rt_rule(uint8_t* mac, ipa_ip_type iptype)
+{
+ if(tx_prop == NULL)
+ {
+ IPACMDBG_H("Tx prop is empty, not adding routing rule.\n");
+ return IPACM_SUCCESS;
+ }
+ if(mac == NULL)
+ {
+ IPACMERR("Client MAC address is empty.\n");
+ return IPACM_FAILURE;
+ }
+ if( (iptype == IPA_IP_v4 && usb_client_rt_info_count_v4 == IPA_LAN_TO_LAN_MAX_USB_CLIENT)
+ || (iptype == IPA_IP_v6 && usb_client_rt_info_count_v6 == IPA_LAN_TO_LAN_MAX_USB_CLIENT))
+ {
+ IPACMDBG_H("USB client number has reached maximum.\n");
+ return IPACM_FAILURE;
+ }
+ if(IPACM_Lan::wlan_to_usb_hdr_proc_ctx.valid == false)
+ {
+ IPACMDBG_H("WLAN to USB hdr proc ctx has not been set, don't add USB routing rule.\n");
+ return IPACM_FAILURE;
+ }
+
+ IPACMDBG_H("Receive USB 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;
+ int position, num_rt_rule;
+
+ if(iptype == IPA_IP_v4)
+ {
+ for(i=0; i<usb_client_rt_info_count_v4; i++)
+ {
+ if(memcmp(eth_bridge_get_client_rt_info_ptr(i, iptype)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, iptype)->mac)) == 0)
+ {
+ IPACMDBG_H("The client's routing rule was added before.\n");
+ return IPACM_SUCCESS;
+ }
+ }
+ memcpy(eth_bridge_get_client_rt_info_ptr(usb_client_rt_info_count_v4, iptype)->mac, mac,
+ sizeof(eth_bridge_get_client_rt_info_ptr(usb_client_rt_info_count_v4, iptype)->mac));
+ }
+ else
+ {
+ for(i=0; i<usb_client_rt_info_count_v6; i++)
+ {
+ if(memcmp(eth_bridge_get_client_rt_info_ptr(i, iptype)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, iptype)->mac)) == 0)
+ {
+ IPACMDBG_H("The client's routing rule was added before.\n");
+ return IPACM_SUCCESS;
+ }
+ }
+ memcpy(eth_bridge_get_client_rt_info_ptr(usb_client_rt_info_count_v6, iptype)->mac, mac,
+ sizeof(eth_bridge_get_client_rt_info_ptr(usb_client_rt_info_count_v6, iptype)->mac));
+ }
+
+ if(iptype == IPA_IP_v4)
+ {
+ num_rt_rule = each_client_rt_rule_count_v4;
+ }
+ else
+ {
+ num_rt_rule = each_client_rt_rule_count_v6;
+ }
+
+ len = sizeof(ipa_ioc_add_rt_rule) + num_rt_rule * sizeof(ipa_rt_rule_add);
+ rt_rule_table = (ipa_ioc_add_rt_rule*)malloc(len);
+ if(rt_rule_table == NULL)
+ {
+ IPACMERR("Failed to allocate memory.\n");
+ return IPACM_FAILURE;
+ }
+ memset(rt_rule_table, 0, len);
+
+ rt_rule_table->commit = 1;
+ rt_rule_table->ip = iptype;
+ rt_rule_table->num_rules = num_rt_rule;
+
+ if(iptype == IPA_IP_v4)
+ {
+ strncpy(rt_rule_table->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_usb_wlan_v4.name, sizeof(rt_rule_table->rt_tbl_name));
+ }
+ else
+ {
+ strncpy(rt_rule_table->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_usb_wlan_v6.name, sizeof(rt_rule_table->rt_tbl_name));
+ }
+
+ memset(&rt_rule, 0, sizeof(ipa_rt_rule_add));
+ rt_rule.at_rear = false;
+ rt_rule.status = -1;
+ rt_rule.rt_rule_hdl = -1;
+
+ rt_rule.rule.hdr_hdl = 0;
+ rt_rule.rule.hdr_proc_ctx_hdl = IPACM_Lan::wlan_to_usb_hdr_proc_ctx.proc_ctx_hdl;
+ position = 0;
+ for(i=0; i<iface_query->num_tx_props; i++)
+ {
+ if(tx_prop->tx[i].ip == iptype)
+ {
+ if(position >= num_rt_rule)
+ {
+ IPACMERR("Number of routing rules already exceeds limit for iptype %d.\n", iptype);
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ rt_rule.rule.dst = tx_prop->tx[i].dst_pipe;
+ memcpy(&rt_rule.rule.attrib, &tx_prop->tx[i].attrib, sizeof(rt_rule.rule.attrib));
+ if(IPACM_Lan::wlan_hdr_type == IPA_HDR_L2_ETHERNET_II)
+ {
+ rt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II;
+ }
+ else if(IPACM_Lan::wlan_hdr_type == IPA_HDR_L2_802_3)
+ {
+ rt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3;
+ }
+ else
+ {
+ IPACMERR("WLAN header type is not expected.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ memcpy(rt_rule.rule.attrib.dst_mac_addr, mac, sizeof(rt_rule.rule.attrib.dst_mac_addr));
+ memset(rt_rule.rule.attrib.dst_mac_addr_mask, 0xFF, sizeof(rt_rule.rule.attrib.dst_mac_addr_mask));
+
+ memcpy(&(rt_rule_table->rules[position]), &rt_rule, sizeof(rt_rule_table->rules[position]));
+ position++;
+ }
+ }
+
+ if(false == m_routing.AddRoutingRule(rt_rule_table))
+ {
+ IPACMERR("Routing rule addition failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ else
+ {
+ for(i=0; i<num_rt_rule; i++)
+ {
+ if(iptype == IPA_IP_v4)
+ {
+ eth_bridge_get_client_rt_info_ptr(usb_client_rt_info_count_v4, iptype)->rt_rule_hdl[i] = rt_rule_table->rules[i].rt_rule_hdl;
+ }
+ else
+ {
+ eth_bridge_get_client_rt_info_ptr(usb_client_rt_info_count_v6, iptype)->rt_rule_hdl[i] = rt_rule_table->rules[i].rt_rule_hdl;
+ }
+ }
+ }
+
+ if(iptype == IPA_IP_v4)
+ {
+ usb_client_rt_info_count_v4++;
+ IPACMDBG_H("Now the number of IPv4 rt rule info is %d.\n", usb_client_rt_info_count_v4);
+ }
+ else
+ {
+ usb_client_rt_info_count_v6++;
+ IPACMDBG_H("Now the number of IPv6 rt rule info is %d.\n", usb_client_rt_info_count_v6);
+ }
+
+fail:
+ if(rt_rule_table != NULL)
+ {
+ free(rt_rule_table);
+ }
+ return res;
+}
+
+int IPACM_Lan::eth_bridge_del_usb_client_rt_rule(uint8_t* mac)
+{
+ if(tx_prop == NULL)
+ {
+ IPACMDBG_H("Tx prop is empty, not deleting routing rule.\n");
+ return IPACM_SUCCESS;
+ }
+ if(mac == NULL)
+ {
+ IPACMERR("Client MAC address is empty.\n");
+ return IPACM_FAILURE;
+ }
+
+ IPACMDBG_H("Receive USB client MAC 0x%02x%02x%02x%02x%02x%02x.\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+
+ int i, position;
+ /* delete rule from IPv4 rt table first */
+ for(i=0; i<usb_client_rt_info_count_v4; i++)
+ {
+ if(memcmp(eth_bridge_get_client_rt_info_ptr(i, IPA_IP_v4)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, IPA_IP_v4)->mac)) == 0)
+ {
+ position = i;
+ IPACMDBG_H("The client is found at position %d.\n", position);
+ break;
+ }
+ }
+ if(i == usb_client_rt_info_count_v4)
+ {
+ IPACMERR("The client is not found.\n");
+ return IPACM_FAILURE;
+ }
+
+ for(i=0; i<each_client_rt_rule_count_v4; i++)
+ {
+ if(m_routing.DeleteRoutingHdl(eth_bridge_get_client_rt_info_ptr(position, IPA_IP_v4)->rt_rule_hdl[i], IPA_IP_v4) == false)
+ {
+ IPACMERR("Failed to delete routing rule %d.\n", i);
+ return IPACM_FAILURE;
+ }
+ }
+
+ for(i=position+1; i<usb_client_rt_info_count_v4; i++)
+ {
+ memcpy(eth_bridge_get_client_rt_info_ptr(i-1, IPA_IP_v4), eth_bridge_get_client_rt_info_ptr(i, IPA_IP_v4), client_rt_info_size_v4);
+ }
+ memset(eth_bridge_get_client_rt_info_ptr(usb_client_rt_info_count_v4-1, IPA_IP_v4), 0, client_rt_info_size_v4);
+ usb_client_rt_info_count_v4--;
+ IPACMDBG_H("Now the number of IPv4 rt rule info is %d.\n", usb_client_rt_info_count_v4);
+
+ /*delete rule from IPv6 rt table */
+ for(i=0; i<usb_client_rt_info_count_v6; i++)
+ {
+ if(memcmp(eth_bridge_get_client_rt_info_ptr(i, IPA_IP_v6)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, IPA_IP_v6)->mac)) == 0)
+ {
+ position = i;
+ IPACMDBG_H("The client is found at position %d.\n", position);
+ break;
+ }
+ }
+ if(i == usb_client_rt_info_count_v6)
+ {
+ IPACMERR("The client is not found.\n");
+ return IPACM_FAILURE;
+ }
+
+ for(i=0; i<each_client_rt_rule_count_v6; i++)
+ {
+ if(m_routing.DeleteRoutingHdl(eth_bridge_get_client_rt_info_ptr(position, IPA_IP_v6)->rt_rule_hdl[i], IPA_IP_v6) == false)
+ {
+ IPACMERR("Failed to delete routing rule %d.\n", i);
+ return IPACM_FAILURE;
+ }
+ }
+
+ for(i=position+1; i<usb_client_rt_info_count_v6; i++)
+ {
+ memcpy(eth_bridge_get_client_rt_info_ptr(i-1, IPA_IP_v6), eth_bridge_get_client_rt_info_ptr(i, IPA_IP_v6), client_rt_info_size_v6);
+ }
+ memset(eth_bridge_get_client_rt_info_ptr(usb_client_rt_info_count_v6-1, IPA_IP_v6), 0, client_rt_info_size_v6);
+ usb_client_rt_info_count_v6--;
+ IPACMDBG_H("Now the number of IPv6 rt rule info is %d.\n", usb_client_rt_info_count_v6);
+
+ return IPACM_SUCCESS;
+}
+
+eth_bridge_client_rt_info* IPACM_Lan::eth_bridge_get_client_rt_info_ptr(uint8_t index, ipa_ip_type iptype)
+{
+ void* result;
+ if(iptype == IPA_IP_v4)
+ {
+ result = (void*)((void*)eth_bridge_usb_client_rt_info_v4 + index * client_rt_info_size_v4);
+ }
+ else
+ {
+ result = (void*)((void*)eth_bridge_usb_client_rt_info_v6 + index * client_rt_info_size_v6);
+ }
+ return (eth_bridge_client_rt_info*)result;
+}
+
+void IPACM_Lan::eth_bridge_add_usb_client(uint8_t* mac)
+{
+ if(IPACM_Lan::num_usb_client == IPA_LAN_TO_LAN_MAX_USB_CLIENT)
+ {
+ IPACMDBG_H("USB client table is already full.\n");
+ return;
+ }
+
+ if(mac == NULL)
+ {
+ IPACMERR("Mac address is empty.\n");
+ return;
+ }
+
+ memcpy(IPACM_Lan::eth_bridge_usb_client[IPACM_Lan::num_usb_client].mac, mac, sizeof(IPACM_Lan::eth_bridge_usb_client[IPACM_Lan::num_usb_client].mac));
+ IPACM_Lan::num_usb_client++;
+ return;
+}
+
+void IPACM_Lan::eth_bridge_del_usb_client(uint8_t* mac)
+{
+ if(mac == NULL)
+ {
+ IPACMERR("Mac address is empty.\n");
+ return;
+ }
+
+ int i, j;
+ for(i=0; i<IPACM_Lan::num_usb_client; i++)
+ {
+ if(memcmp(IPACM_Lan::eth_bridge_usb_client[i].mac, mac, sizeof(IPACM_Lan::eth_bridge_usb_client[i].mac)) == 0)
+ {
+ IPACMDBG_H("Found USB client at position %d.\n", i);
+ break;
+ }
+ }
+
+ if(i == IPACM_Lan::num_usb_client)
+ {
+ IPACMDBG_H("Not finding the USB client.\n");
+ return;
+ }
+
+ for(j=i+1; j<IPACM_Lan::num_usb_client; j++)
+ {
+ memcpy(IPACM_Lan::eth_bridge_usb_client[j-1].mac, IPACM_Lan::eth_bridge_usb_client[j].mac, sizeof(IPACM_Lan::eth_bridge_usb_client[j].mac));
+ IPACM_Lan::eth_bridge_usb_client[j-1].ipa_if_num = IPACM_Lan::eth_bridge_usb_client[j].ipa_if_num;
+ }
+ IPACM_Lan::num_usb_client--;
+ return;
+}
+
+int IPACM_Lan::eth_bridge_get_hdr_template_hdl(uint32_t* hdr_hdl)
+{
+ if(hdr_hdl == NULL)
+ {
+ IPACMDBG_H("Hdr handle pointer is empty.\n");
+ return IPACM_FAILURE;
+ }
+
+ struct ipa_ioc_get_hdr hdr;
+ memset(&hdr, 0, sizeof(hdr));
+
+ memcpy(hdr.name, tx_prop->tx[0].hdr_name, sizeof(hdr.name));
+ if(m_header.GetHeaderHandle(&hdr) == false)
+ {
+ IPACMERR("Failed to get template hdr hdl.\n");
+ return IPACM_FAILURE;
+ }
+
+ *hdr_hdl = hdr.hdl;
+ return IPACM_SUCCESS;
+}
+
+int IPACM_Lan::del_hdr_proc_ctx()
+{
+ if(IPACM_Lan::usb_to_wlan_hdr_proc_ctx.valid == true)
+ {
+ if(m_header.DeleteHeaderProcCtx(IPACM_Lan::usb_to_wlan_hdr_proc_ctx.proc_ctx_hdl) == false)
+ {
+ IPACMERR("Failed to delete usb to wlan hdr proc ctx.\n");
+ return IPACM_FAILURE;
+ }
+ IPACM_Lan::usb_to_wlan_hdr_proc_ctx.valid = false;
+
+ ipacm_cmd_q_data evt_data;
+ memset(&evt_data, 0, sizeof(ipacm_cmd_q_data));
+
+ ipacm_event_data_fid* fid;
+ fid = (ipacm_event_data_fid*)malloc(sizeof(ipacm_event_data_fid));
+ if(fid == NULL)
+ {
+ IPACMERR("Unable to allocate memory.\n");
+ return IPACM_FAILURE;
+ }
+ memset(fid, 0, sizeof(ipacm_event_data_fid));
+ fid->if_index = ipa_if_num;
+
+ evt_data.evt_data = fid;
+ evt_data.event = IPA_ETH_BRIDGE_HDR_PROC_CTX_UNSET_EVENT;
+ IPACMDBG_H("Posting event IPA_ETH_BRIDGE_HDR_PROC_CTX_UNSET_EVENT\n");
+ IPACM_EvtDispatcher::PostEvt(&evt_data);
+ }
+
+ if(IPACM_Lan::wlan_to_usb_hdr_proc_ctx.valid == true)
+ {
+ if(m_header.DeleteHeaderProcCtx(IPACM_Lan::wlan_to_usb_hdr_proc_ctx.proc_ctx_hdl) == false)
+ {
+ IPACMERR("Failed to delete wlan to usb hdr proc ctx.\n");
+ return IPACM_FAILURE;
+ }
+ IPACM_Lan::wlan_to_usb_hdr_proc_ctx.valid = false;
+ }
+
+ if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == WLAN_IF)
+ {
+ if(IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.valid == true)
+ {
+ if(m_header.DeleteHeaderProcCtx(IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.proc_ctx_hdl) == false)
+ {
+ IPACMERR("Failed to delete wlan to wlan hdr proc ctx.\n");
+ return IPACM_FAILURE;
+ }
+ IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.valid = false;
+ }
+ }
+ return IPACM_SUCCESS;
+}
+
+
+
diff --git a/ipacm/src/IPACM_LanToLan.cpp b/ipacm/src/IPACM_LanToLan.cpp
index b5bbc18..c3c589b 100644
--- a/ipacm/src/IPACM_LanToLan.cpp
+++ b/ipacm/src/IPACM_LanToLan.cpp
@@ -1095,8 +1095,8 @@
}
memset(new_conn, 0, sizeof(ipacm_event_connection));
new_conn->iptype = IPA_IP_v6;
- memcpy(new_conn->src_ipv6_addr, client->ip.ipv6_addr, sizeof(client->ip.ipv6_addr));
- memcpy(new_conn->dst_ipv6_addr, it->second.ip.ipv6_addr, sizeof(it->second.ip.ipv6_addr));
+ memcpy(new_conn->src_ipv6_addr, client->ip.ipv6_addr, sizeof(new_conn->src_ipv6_addr));
+ memcpy(new_conn->dst_ipv6_addr, it->second.ip.ipv6_addr, sizeof(new_conn->dst_ipv6_addr));
memset(&evt, 0, sizeof(evt));
evt.event = IPA_LAN_TO_LAN_NEW_CONNECTION;
diff --git a/ipacm/src/IPACM_Main.cpp b/ipacm/src/IPACM_Main.cpp
index d554bac..39a31f5 100644
--- a/ipacm/src/IPACM_Main.cpp
+++ b/ipacm/src/IPACM_Main.cpp
@@ -652,9 +652,11 @@
IPACMDBG_H("In main()\n");
IPACM_Neighbor *neigh = new IPACM_Neighbor();
IPACM_IfaceManager *ifacemgr = new IPACM_IfaceManager();
+#ifndef FEATURE_ETH_BRIDGE_LE
#ifndef FEATURE_IPA_ANDROID
IPACM_LanToLan* lan2lan = new IPACM_LanToLan();
#endif /* defined(FEATURE_IPA_ANDROID)*/
+#endif
IPACM_ConntrackClient *cc = IPACM_ConntrackClient::GetInstance();
CtList = new IPACM_ConntrackListener();
diff --git a/ipacm/src/IPACM_Wlan.cpp b/ipacm/src/IPACM_Wlan.cpp
index cb6fb2a..83e474e 100644
--- a/ipacm/src/IPACM_Wlan.cpp
+++ b/ipacm/src/IPACM_Wlan.cpp
@@ -58,6 +58,12 @@
uint32_t* IPACM_Wlan::dummy_flt_rule_hdl_v6 = NULL;
int IPACM_Wlan::num_wlan_ap_iface = 0;
+lan2lan_flt_rule_hdl IPACM_Wlan::self_client_flt_rule_hdl_v4[IPA_LAN_TO_LAN_MAX_WLAN_CLIENT];
+lan2lan_flt_rule_hdl IPACM_Wlan::self_client_flt_rule_hdl_v6[IPA_LAN_TO_LAN_MAX_WLAN_CLIENT];
+
+lan2lan_flt_rule_hdl IPACM_Wlan::usb_client_flt_rule_hdl_v4[IPA_LAN_TO_LAN_MAX_USB_CLIENT];
+lan2lan_flt_rule_hdl IPACM_Wlan::usb_client_flt_rule_hdl_v6[IPA_LAN_TO_LAN_MAX_USB_CLIENT];
+
IPACM_Wlan::IPACM_Wlan(int iface_index) : IPACM_Lan(iface_index)
{
#define WLAN_AMPDU_DEFAULT_FILTER_RULES 3
@@ -108,6 +114,60 @@
IPACMDBG_H("Now the number of wlan AP iface is %d\n", IPACM_Wlan::num_wlan_ap_iface);
add_dummy_flt_rule();
+ memset(wlan_guest_ap_flt_rule_hdl_v4, 0, IPA_MAX_PRIVATE_SUBNET_ENTRIES * sizeof(uint32_t));
+ wlan_guest_ap_flt_rule_hdl_v6 = 0;
+ is_guest_ap = false;
+ num_usb_client = 0;
+
+ memset(eth_bridge_usb_client_flt_info, 0, IPA_LAN_TO_LAN_MAX_USB_CLIENT * sizeof(eth_bridge_client_flt_info));
+ num_usb_client = 0;
+ eth_bridge_wlan_client_rt_from_usb_info_v4 = NULL;
+ eth_bridge_wlan_client_rt_from_usb_info_v6 = NULL;
+ eth_bridge_wlan_client_rt_from_wlan_info_v4 = NULL;
+ eth_bridge_wlan_client_rt_from_wlan_info_v6 = NULL;
+ if(tx_prop != NULL)
+ {
+#ifdef FEATURE_ETH_BRIDGE_LE
+ client_rt_info_size_v4 = sizeof(eth_bridge_client_rt_info) + each_client_rt_rule_count_v4 * sizeof(uint32_t);
+ eth_bridge_wlan_client_rt_from_usb_info_v4 = (eth_bridge_client_rt_info*)calloc(IPA_LAN_TO_LAN_MAX_WLAN_CLIENT, client_rt_info_size_v4);
+ eth_bridge_wlan_client_rt_from_wlan_info_v4 = (eth_bridge_client_rt_info*)calloc(IPA_LAN_TO_LAN_MAX_WLAN_CLIENT, client_rt_info_size_v4);
+
+ client_rt_info_size_v6 = sizeof(eth_bridge_client_rt_info) + each_client_rt_rule_count_v6 * sizeof(uint32_t);
+ eth_bridge_wlan_client_rt_from_usb_info_v6 = (eth_bridge_client_rt_info*)calloc(IPA_LAN_TO_LAN_MAX_WLAN_CLIENT, client_rt_info_size_v6);
+ eth_bridge_wlan_client_rt_from_wlan_info_v6 = (eth_bridge_client_rt_info*)calloc(IPA_LAN_TO_LAN_MAX_WLAN_CLIENT, client_rt_info_size_v6);
+#endif
+ }
+ wlan_client_rt_from_usb_info_count_v4 = 0;
+ wlan_client_rt_from_usb_info_count_v6 = 0;
+ wlan_client_rt_from_wlan_info_count_v4 = 0;
+ wlan_client_rt_from_wlan_info_count_v6 = 0;
+#ifdef FEATURE_ETH_BRIDGE_LE
+ if(iface_query != NULL)
+ {
+ if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == WLAN_IF && tx_prop != NULL)
+ {
+ if(IPACM_Lan::wlan_hdr_type != IPA_HDR_L2_NONE && tx_prop->tx[0].hdr_l2_type != IPACM_Lan::wlan_hdr_type)
+ {
+ IPACMERR("The WLAN header format is not consistent! Now header format is %d.\n", tx_prop->tx[0].hdr_l2_type);
+ }
+ else
+ {
+ if(wlan_ap_index == 0)
+ {
+ if(eth_bridge_get_hdr_template_hdl(&IPACM_Lan::wlan_hdr_template_hdl) == IPACM_FAILURE)
+ {
+ IPACMERR("Failed to setup wlan hdr template.\n");
+ }
+ else
+ {
+ IPACM_Lan::wlan_hdr_type = tx_prop->tx[0].hdr_l2_type;
+ add_hdr_proc_ctx();
+ }
+ }
+ }
+ }
+ }
+#endif
return;
}
@@ -251,7 +311,10 @@
add_dummy_private_subnet_flt_rule(data->iptype);
handle_private_subnet_android(data->iptype);
#else
- handle_private_subnet(data->iptype);
+ if(wlan_ap_index == 0)
+ {
+ handle_private_subnet(data->iptype);
+ }
#endif
if (IPACM_Wan::isWanUP())
@@ -341,6 +404,9 @@
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);
@@ -414,6 +480,36 @@
ipa_interface_index = iface_ipa_index_query(data->if_index);
if (ipa_interface_index == ipa_if_num)
{
+#ifdef FEATURE_ETH_BRIDGE_LE
+ int i;
+ for(i=0; i<data->num_of_attribs; i++)
+ {
+ 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(IPACM_Lan::usb_to_wlan_hdr_proc_ctx.valid == true)
+ {
+ eth_bridge_add_wlan_client_rt_rule(data->attribs[i].u.mac_addr, SRC_USB, IPA_IP_v4);
+ eth_bridge_add_wlan_client_rt_rule(data->attribs[i].u.mac_addr, SRC_USB, 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);
+ break;
+ }
+ }
+#endif
IPACMDBG_H("Received IPA_WLAN_CLIENT_ADD_EVENT\n");
handle_wlan_client_init_ex(data);
}
@@ -427,6 +523,16 @@
if (ipa_interface_index == ipa_if_num)
{
IPACMDBG_H("Received IPA_WLAN_CLIENT_DEL_EVENT\n");
+#ifdef FEATURE_ETH_BRIDGE_LE
+ eth_bridge_del_wlan_client_rt_rule(data->mac_addr, SRC_WLAN);
+ if(IPACM_Lan::usb_to_wlan_hdr_proc_ctx.valid == true)
+ {
+ eth_bridge_del_wlan_client_rt_rule(data->mac_addr, SRC_USB);
+ }
+ 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);
+#endif
/* support lan2lan ipa-HW feature*/
handle_lan2lan_msg_post(data->mac_addr, IPA_LAN_CLIENT_DISCONNECT, IPA_IP_v4);
handle_lan2lan_msg_post(data->mac_addr, IPA_LAN_CLIENT_DISCONNECT, IPA_IP_v6);
@@ -529,6 +635,104 @@
IPACM_Iface::handle_software_routing_disable();
break;
+ case IPA_ETH_BRIDGE_USB_CLIENT_ADD_EVENT:
+ {
+ IPACMDBG_H("Received IPA_ETH_BRIDGE_USB_CLIENT_ADD_EVENT event.\n");
+ ipacm_event_data_mac* mac = (ipacm_event_data_mac*)param;
+ if(mac != NULL)
+ {
+ if(wlan_ap_index == 0)
+ {
+ if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
+ {
+ eth_bridge_add_usb_client_flt_rule(mac->mac_addr, IPA_IP_v4);
+ }
+ if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
+ {
+ eth_bridge_add_usb_client_flt_rule(mac->mac_addr, IPA_IP_v6);
+ }
+ }
+ }
+ else
+ {
+ IPACMERR("Event MAC is empty.\n");
+ }
+ }
+ break;
+
+ case IPA_ETH_BRIDGE_USB_CLIENT_DEL_EVENT:
+ {
+ IPACMDBG_H("Received IPA_ETH_BRIDGE_USB_CLIENT_DEL_EVENT event.\n");
+ ipacm_event_data_mac* mac = (ipacm_event_data_mac*)param;
+ if(mac != NULL)
+ {
+ if(wlan_ap_index == 0)
+ {
+ if(eth_bridge_del_usb_client_flt_rule(mac->mac_addr) == IPACM_FAILURE)
+ {
+ IPACMDBG_H("Failed to delete usb client MAC based flt rule.\n");
+ }
+ }
+ }
+ else
+ {
+ IPACMERR("Event MAC is empty.\n");
+ }
+ }
+ break;
+
+ case IPA_ETH_BRIDGE_HDR_PROC_CTX_SET_EVENT:
+ {
+ IPACMDBG_H("Received IPA_ETH_BRIDGE_HDR_PROC_CTX_SET_EVENT event.\n");
+ int i;
+ ipacm_event_data_fid* fid = (ipacm_event_data_fid*)param;
+ if(fid == NULL)
+ {
+ IPACMERR("Event data is empty.\n");
+ return;
+ }
+ if(fid->if_index == ipa_if_num)
+ {
+ IPACMDBG_H("The event was sent by the same interface, ignore.\n");
+ return;
+ }
+ 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_USB, IPA_IP_v4);
+ eth_bridge_add_wlan_client_rt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac, SRC_USB, IPA_IP_v6);
+ }
+ }
+ }
+ break;
+
+ case IPA_ETH_BRIDGE_HDR_PROC_CTX_UNSET_EVENT:
+ {
+ IPACMDBG_H("Received IPA_ETH_BRIDGE_HDR_PROC_CTX_UNSET_EVENT event.\n");
+ int i;
+ ipacm_event_data_fid* fid = (ipacm_event_data_fid*)param;
+ if(fid == NULL)
+ {
+ IPACMERR("Event data is empty.\n");
+ return;
+ }
+ if(fid->if_index == ipa_if_num)
+ {
+ IPACMDBG_H("The event was sent by the same interface, ignore.\n");
+ return;
+ }
+
+ 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_del_wlan_client_rt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac, SRC_USB);
+ }
+ }
+ }
+ break;
+
default:
break;
}
@@ -595,6 +799,13 @@
IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
return IPACM_SUCCESS;
}
+#ifdef FEATURE_ETH_BRIDGE_LE
+ if(wlan_ap_index != 0)
+ {
+ IPACMDBG_H("Install frag/multicast/broadcast rules only for the first AP.\n");
+ return IPACM_SUCCESS;
+ }
+#endif
/* construct ipa_ioc_add_flt_rule with default filter rules */
if (iptype == IPA_IP_v4)
@@ -604,11 +815,15 @@
IPACMERR("Dummy ipv4 flt rule has not been installed.\n");
return IPACM_FAILURE;
}
+#ifdef FEATURE_ETH_BRIDGE_LE
+ offset = 0;
+#else
#ifndef CT_OPT
offset = wlan_ap_index * (IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
#else
offset = wlan_ap_index * (IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet)
- + NUM_TCP_CTL_FLT_RULE;
+ + NUM_TCP_CTL_FLT_RULE;
+#endif
#endif
#ifdef FEATURE_IPA_ANDROID
@@ -639,14 +854,20 @@
/* Configuring Fragment Filtering Rule */
IPACMDBG_H("rx property attrib mask:0x%x\n", rx_prop->rx[0].attrib.attrib_mask);
memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib));
-
+#ifdef FEATURE_ETH_BRIDGE_LE
+ /* remove meta data mask */
+ flt_rule.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA);
+#endif
flt_rule.rule.attrib.attrib_mask |= IPA_FLT_FRAGMENT;
flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v4[offset];
memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy));
/* Configuring Multicast Filtering Rule */
memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib));
-
+#ifdef FEATURE_ETH_BRIDGE_LE
+ /* remove meta data mask */
+ flt_rule.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA);
+#endif
flt_rule.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
flt_rule.rule.attrib.u.v4.dst_addr_mask = 0xF0000000;
flt_rule.rule.attrib.u.v4.dst_addr = 0xE0000000;
@@ -689,13 +910,17 @@
IPACMERR("Dummy ipv6 flt rule has not been installed.\n");
return IPACM_FAILURE;
}
+#ifdef FEATURE_ETH_BRIDGE_LE
+ offset = 1 + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_USB_CLIENT;
+#else
#ifndef CT_OPT
- offset = wlan_ap_index * (IPV6_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR)
- + MAX_OFFLOAD_PAIR;
+ offset = wlan_ap_index * (IPV6_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR) + MAX_OFFLOAD_PAIR;
#else
offset = wlan_ap_index * (IPV6_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR)
- + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR;
+ + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR;
#endif
+#endif
+
len = sizeof(struct ipa_ioc_mdfy_flt_rule) + (IPV6_DEFAULT_FILTERTING_RULES * sizeof(struct ipa_flt_rule_mdfy));
pFilteringTable = (struct ipa_ioc_mdfy_flt_rule *)calloc(1, len);
if (!pFilteringTable)
@@ -720,6 +945,10 @@
/* Configuring Multicast Filtering Rule */
memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib));
+#ifdef FEATURE_ETH_BRIDGE_LE
+ /* remove meta data mask */
+ flt_rule.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA);
+#endif
flt_rule.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
flt_rule.rule.attrib.u.v6.dst_addr_mask[0] = 0xFF000000;
flt_rule.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000;
@@ -870,13 +1099,16 @@
IPACMERR("Dummy ipv4 flt rule has not been installed.\n");
return IPACM_FAILURE;
}
-
+#ifdef FEATURE_ETH_BRIDGE_LE
+ offset = IPV4_DEFAULT_FILTERTING_RULES + IPACM_Iface::ipacmcfg->ipa_num_private_subnet + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_USB_CLIENT;
+#else
#ifndef CT_OPT
offset = wlan_ap_index * (IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet)
- + IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR;
+ + IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR;
#else
offset = wlan_ap_index * (IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet)
- + IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR;
+ + IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR;
+#endif
#endif
len = sizeof(struct ipa_ioc_mdfy_flt_rule) + (IPACM_Iface::ipacmcfg->ipa_num_private_subnet) * sizeof(struct ipa_flt_rule_mdfy);
@@ -912,6 +1144,10 @@
memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib));
flt_rule.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
+#ifdef FEATURE_ETH_BRIDGE_LE
+ /* remove meta data mask */
+ flt_rule.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA);
+#endif
for (i = 0; i < (IPACM_Iface::ipacmcfg->ipa_num_private_subnet); i++)
{
@@ -1030,23 +1266,32 @@
if(iptype == IPA_IP_v4)
{
+#ifdef FEATURE_ETH_BRIDGE_LE
+ offset = IPV4_DEFAULT_FILTERTING_RULES + 2 * IPACM_Iface::ipacmcfg->ipa_num_private_subnet
+ + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_USB_CLIENT;
+#else
#ifndef CT_OPT
offset = 2*(IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
#else
offset = 2*(IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
#endif
-
#ifdef FEATURE_IPA_ANDROID
offset = offset + 2 * (IPA_MAX_PRIVATE_SUBNET_ENTRIES - IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
#endif
+#endif
}
else
{
+#ifdef FEATURE_ETH_BRIDGE_LE
+ offset = IPV6_DEFAULT_FILTERTING_RULES + 1 + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_USB_CLIENT + NUM_IPV6_PREFIX_FLT_RULE
+ + NUM_IPV6_ICMP_FLT_RULE;
+#else
#ifndef CT_OPT
offset = 2*(IPV6_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR) + NUM_IPV6_PREFIX_FLT_RULE + NUM_IPV6_ICMP_FLT_RULE;
#else
offset = 2*(IPV6_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR) + NUM_IPV6_PREFIX_FLT_RULE + NUM_IPV6_ICMP_FLT_RULE;
#endif
+#endif
}
for(cnt=0; cnt<prop->num_ext_props; cnt++)
@@ -1849,6 +2094,14 @@
IPACMERR("Invalid iptype: 0x%x\n", ip_type);
goto fail;
}
+#ifdef FEATURE_ETH_BRIDGE_LE
+ if(wlan_ap_index == 0)
+ {
+ IPACM_Lan::wlan_hdr_type = IPA_HDR_L2_NONE;
+ IPACM_Lan::wlan_hdr_template_hdl = 0;
+ del_hdr_proc_ctx();
+ }
+#endif
/* delete wan filter rule */
if (IPACM_Wan::isWanUP() && rx_prop != NULL)
@@ -1867,7 +2120,21 @@
/* Delete v4 filtering rules */
if (ip_type != IPA_IP_v6 && rx_prop != NULL)
{
- IPACMDBG_H("Delete default v4 filter rules\n");
+#ifdef FEATURE_ETH_BRIDGE_LE
+ if(wlan_ap_index == 0)
+ {
+ /* delete default filter rules */
+ for(i=0; i<IPV4_DEFAULT_FILTERTING_RULES; i++)
+ {
+ if(reset_to_dummy_flt_rule(IPA_IP_v4, dft_v4fl_rule_hdl[i]) == IPACM_FAILURE)
+ {
+ IPACMERR("Error deleting dft IPv4 flt rules.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ }
+ }
+#else
/* delete default filter rules */
for(i=0; i<IPV4_DEFAULT_FILTERTING_RULES; i++)
{
@@ -1878,6 +2145,24 @@
goto fail;
}
}
+#endif
+ IPACMDBG_H("Deleted default v4 filter rules successfully.\n");
+#ifdef FEATURE_ETH_BRIDGE_LE
+ if(is_guest_ap == true)
+ {
+ IPACMDBG_H("Delete wlan guest ap v4 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");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ }
+ }
+ IPACMDBG_H("Deleted guest ap v4 filter rules successfully.\n");
+#endif
/* delete icmp filter rules */
if(wlan_ap_index == 0)
@@ -1889,6 +2174,7 @@
goto fail;
}
}
+#ifndef FEATURE_ETH_BRIDGE_LE
#ifdef CT_OPT
IPACMDBG_H("Delete tcp control flt rules.\n");
/* Delete tcp control flt rules */
@@ -1912,6 +2198,7 @@
goto fail;
}
}
+#endif
IPACMDBG_H("Delete private v4 filter rules\n");
/* delete private-ipv4 filter rules */
@@ -1926,15 +2213,19 @@
}
}
#else
- for(i=0; i<IPACM_Iface::ipacmcfg->ipa_num_private_subnet; i++)
+ if(wlan_ap_index == 0)
{
- if(reset_to_dummy_flt_rule(IPA_IP_v4, private_fl_rule_hdl[i]) == IPACM_FAILURE)
+ for(i=0; i<IPACM_Iface::ipacmcfg->ipa_num_private_subnet; i++)
{
- IPACMERR("Error deleting private subnet IPv4 flt rules.\n");
- res = IPACM_FAILURE;
- goto fail;
+ if(reset_to_dummy_flt_rule(IPA_IP_v4, private_fl_rule_hdl[i]) == IPACM_FAILURE)
+ {
+ IPACMERR("Error deleting private subnet IPv4 flt rules.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
}
}
+ IPACMDBG_H("Deleted private subnet v4 filter rules successfully.\n");
#endif
}
@@ -1943,6 +2234,19 @@
{
IPACMDBG_H("Delete default %d v6 filter rules\n", IPV6_DEFAULT_FILTERTING_RULES);
/* delete default filter rules */
+#ifdef FEATURE_ETH_BRIDGE_LE
+ if(wlan_ap_index == 0)
+ {
+ for(i=0; i<IPV6_DEFAULT_FILTERTING_RULES; i++)
+ {
+ if(reset_to_dummy_flt_rule(IPA_IP_v6, dft_v6fl_rule_hdl[i]) == IPACM_FAILURE)
+ {
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ }
+ }
+#else
for(i=0; i<IPV6_DEFAULT_FILTERTING_RULES; i++)
{
if(reset_to_dummy_flt_rule(IPA_IP_v6, dft_v6fl_rule_hdl[i]) == IPACM_FAILURE)
@@ -1951,6 +2255,10 @@
goto fail;
}
}
+#endif
+ IPACMDBG_H("Deleted default v6 filter rules successfully.\n");
+
+#ifndef FEATURE_ETH_BRIDGE_LE
#ifdef CT_OPT
IPACMDBG_H("Delete tcp control flt rules.\n");
/* Delete tcp control flt rules */
@@ -1963,19 +2271,32 @@
}
}
#endif
- IPACMDBG_H("Delete lan2lan v6 filter rules\n");
- /* delete lan2lan ipv6 filter rules */
+ IPACMDBG_H("Delete lan2lan v6 flt rules.\n");
+ /* delete lan2lan ipv4 flt rules */
for(i=0; i<MAX_OFFLOAD_PAIR; i++)
{
if(reset_to_dummy_flt_rule(IPA_IP_v6, lan2lan_flt_rule_hdl_v6[i].rule_hdl) == IPACM_FAILURE)
{
- IPACMERR("Error deleting lan2lan IPv6 flt rules.\n");
+ IPACMERR("Error deleting lan2lan IPv4 flt rules.\n");
res = IPACM_FAILURE;
goto fail;
}
}
+#endif
+#ifdef FEATURE_ETH_BRIDGE_LE
+ if(is_guest_ap == true)
+ {
+ if(reset_to_dummy_flt_rule(IPA_IP_v6, wlan_guest_ap_flt_rule_hdl_v6) == IPACM_FAILURE)
+ {
+ IPACMERR("Error deleting wlan guest ap IPv6 flt rules.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ }
+ IPACMDBG_H("Deleted wlan guest ap v6 filter rules successfully.\n");
+#endif
}
- IPACMDBG_H("finished delete default filtering rules\n ");
+ IPACMDBG_H("finished delete filtering rules\n ");
/* Delete default v4 RT rule */
if (ip_type != IPA_IP_v6)
@@ -2023,6 +2344,13 @@
for (i = 0; i < num_wifi_client; i++)
{
+#ifdef FEATURE_ETH_BRIDGE_LE
+ eth_bridge_del_wlan_client(get_client_memptr(wlan_client, i)->mac);
+ 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_USB);
+#endif
/* First reset nat rules and then route rules */
if(get_client_memptr(wlan_client, i)->ipv4_set == true)
{
@@ -2110,7 +2438,32 @@
{
free(iface_query);
}
-
+#ifdef FEATURE_ETH_BRIDGE_LE
+ if(eth_bridge_usb_client_rt_info_v4 != NULL)
+ {
+ free(eth_bridge_usb_client_rt_info_v4);
+ }
+ if(eth_bridge_usb_client_rt_info_v6 != NULL)
+ {
+ free(eth_bridge_usb_client_rt_info_v6);
+ }
+ if(eth_bridge_wlan_client_rt_from_usb_info_v4 != NULL)
+ {
+ free(eth_bridge_wlan_client_rt_from_usb_info_v4);
+ }
+ if(eth_bridge_wlan_client_rt_from_usb_info_v6 != NULL)
+ {
+ free(eth_bridge_wlan_client_rt_from_usb_info_v6);
+ }
+ if(eth_bridge_wlan_client_rt_from_wlan_info_v4 != NULL)
+ {
+ free(eth_bridge_wlan_client_rt_from_wlan_info_v4);
+ }
+ if(eth_bridge_wlan_client_rt_from_wlan_info_v6 != NULL)
+ {
+ free(eth_bridge_wlan_client_rt_from_wlan_info_v6);
+ }
+#endif
is_active = false;
post_del_self_evt();
@@ -2524,6 +2877,10 @@
IPACMERR("Either v4 or v6 dummy filtering rule handle is not empty.\n");
return;
}
+#ifdef FEATURE_ETH_BRIDGE_LE
+ num_v4_dummy_rule = IPV4_DEFAULT_FILTERTING_RULES + IPACM_Iface::ipacmcfg->ipa_num_private_subnet + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_USB_CLIENT + IPACM_Iface::ipacmcfg->ipa_num_private_subnet;
+ num_v6_dummy_rule = IPV6_DEFAULT_FILTERTING_RULES + 1 + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_USB_CLIENT;
+#else
#ifndef CT_OPT
num_v4_dummy_rule = 2*(IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
num_v6_dummy_rule = 2*(IPV6_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR);
@@ -2531,10 +2888,10 @@
num_v4_dummy_rule = 2*(IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
num_v6_dummy_rule = 2*(IPV6_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR);
#endif
-
#ifdef FEATURE_IPA_ANDROID
num_v4_dummy_rule = num_v4_dummy_rule - 2* IPACM_Iface::ipacmcfg->ipa_num_private_subnet + 2 * IPA_MAX_PRIVATE_SUBNET_ENTRIES;
#endif
+#endif
IPACM_Wlan::dummy_flt_rule_hdl_v4 = (uint32_t*)malloc(num_v4_dummy_rule * sizeof(uint32_t));
if(IPACM_Wlan::dummy_flt_rule_hdl_v4 == NULL)
@@ -2717,11 +3074,15 @@
num_v4_dummy_rule = 2*(IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
num_v6_dummy_rule = 2*(IPV6_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR);
#endif
-
#ifdef FEATURE_IPA_ANDROID
num_v4_dummy_rule = num_v4_dummy_rule - 2* IPACM_Iface::ipacmcfg->ipa_num_private_subnet + 2 * IPA_MAX_PRIVATE_SUBNET_ENTRIES;
#endif
+#ifdef FEATURE_ETH_BRIDGE_LE
+ num_v4_dummy_rule = IPV4_DEFAULT_FILTERTING_RULES + IPACM_Iface::ipacmcfg->ipa_num_private_subnet + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_USB_CLIENT + IPACM_Iface::ipacmcfg->ipa_num_private_subnet;
+ num_v6_dummy_rule = IPV6_DEFAULT_FILTERTING_RULES + 1 + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_USB_CLIENT;
+#endif
+
if(m_filtering.DeleteFilteringHdls(IPACM_Wlan::dummy_flt_rule_hdl_v4, IPA_IP_v4, num_v4_dummy_rule) == false)
{
IPACMERR("Failed to delete ipv4 dummy flt rules.\n");
@@ -2737,6 +3098,12 @@
IPACM_Wlan::dummy_flt_rule_hdl_v4 = NULL;
free(IPACM_Wlan::dummy_flt_rule_hdl_v6);
IPACM_Wlan::dummy_flt_rule_hdl_v6 = NULL;
+#ifdef FEATURE_ETH_BRIDGE_LE
+ memset(self_client_flt_rule_hdl_v4, 0, IPA_LAN_TO_LAN_MAX_WLAN_CLIENT * sizeof(lan2lan_flt_rule_hdl));
+ memset(self_client_flt_rule_hdl_v6, 0, IPA_LAN_TO_LAN_MAX_WLAN_CLIENT * sizeof(lan2lan_flt_rule_hdl));
+ memset(usb_client_flt_rule_hdl_v4, 0, IPA_LAN_TO_LAN_MAX_USB_CLIENT * sizeof(lan2lan_flt_rule_hdl));
+ memset(usb_client_flt_rule_hdl_v6, 0, IPA_LAN_TO_LAN_MAX_USB_CLIENT * sizeof(lan2lan_flt_rule_hdl));
+#endif
}
return;
}
@@ -2915,3 +3282,1282 @@
}
return IPACM_SUCCESS;
}
+
+int IPACM_Wlan::eth_bridge_add_wlan_guest_ap_flt_rule(ipa_ip_type iptype)
+{
+ if(rx_prop == NULL)
+ {
+ IPACMDBG_H("There is no rx_prop for iface %s, not able to add wlan guest ap filtering rule.\n", dev_name);
+ return IPACM_SUCCESS;
+ }
+ if(is_guest_ap == false)
+ {
+ IPACMDBG_H("This is not WLAN guest AP, do nothing.\n");
+ return IPACM_SUCCESS;
+ }
+
+ int len, i, offset, res = IPACM_SUCCESS;
+ struct ipa_flt_rule_mdfy flt_rule;
+ struct ipa_ioc_mdfy_flt_rule* pFilteringTable = NULL;
+ if(iptype == IPA_IP_v4)
+ {
+ if(IPACM_Wlan::dummy_flt_rule_hdl_v4 == NULL)
+ {
+ IPACMERR("Dummy ipv4 flt rule has not been installed.\n");
+ return IPACM_FAILURE;
+ }
+
+ offset = IPV4_DEFAULT_FILTERTING_RULES;
+ len = sizeof(struct ipa_ioc_mdfy_flt_rule) + (IPACM_Iface::ipacmcfg->ipa_num_private_subnet) * 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);
+
+ pFilteringTable->commit = 1;
+ pFilteringTable->ip = iptype;
+ pFilteringTable->num_rules = (uint8_t)IPACM_Iface::ipacmcfg->ipa_num_private_subnet;
+
+ memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy));
+ flt_rule.status = -1;
+
+ flt_rule.rule.retain_hdr = 1;
+ flt_rule.rule.to_uc = 0;
+ flt_rule.rule.action = IPA_PASS_TO_EXCEPTION;
+ flt_rule.rule.eq_attrib_type = 0;
+
+ memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib));
+ flt_rule.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
+
+ for (i = 0; i < (IPACM_Iface::ipacmcfg->ipa_num_private_subnet); i++)
+ {
+ flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v4[offset+i];
+ flt_rule.rule.attrib.u.v4.dst_addr_mask = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_mask;
+ flt_rule.rule.attrib.u.v4.dst_addr = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_addr;
+ memcpy(&(pFilteringTable->rules[i]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy));
+ }
+
+ if (false == m_filtering.ModifyFilteringRule(pFilteringTable))
+ {
+ IPACMERR("Failed to modify wlan guest AP IPv4 filtering rules.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ /* copy filter rule hdls */
+ for (i = 0; i < IPACM_Iface::ipacmcfg->ipa_num_private_subnet; i++)
+ {
+ wlan_guest_ap_flt_rule_hdl_v4[i] = pFilteringTable->rules[i].rule_hdl;
+ }
+ }
+ else
+ {
+ if(IPACM_Wan::wan_up_v6 == true)
+ {
+ eth_bridge_install_wlan_guest_ap_ipv6_flt_rule();
+ }
+ }
+fail:
+ if(pFilteringTable != NULL)
+ {
+ free(pFilteringTable);
+ }
+ return res;
+}
+
+int IPACM_Wlan::eth_bridge_install_wlan_guest_ap_ipv6_flt_rule()
+{
+ if(rx_prop == NULL)
+ {
+ IPACMDBG_H("There is no rx_prop for iface %s, not able to add wlan guest ap filtering rule.\n", dev_name);
+ return IPACM_SUCCESS;
+ }
+ if(is_guest_ap == false)
+ {
+ IPACMDBG_H("This is not WLAN guest AP, do nothing.\n");
+ return IPACM_SUCCESS;
+ }
+
+ int len, offset, res = IPACM_SUCCESS;
+ struct ipa_flt_rule_mdfy flt_rule;
+ struct ipa_ioc_mdfy_flt_rule* pFilteringTable = NULL;
+
+ if(IPACM_Wlan::dummy_flt_rule_hdl_v6 == NULL)
+ {
+ IPACMERR("Dummy ipv6 flt rule has not been installed.\n");
+ return IPACM_FAILURE;
+ }
+
+ offset = 0;
+ 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);
+
+ pFilteringTable->commit = 1;
+ pFilteringTable->ip = IPA_IP_v6;
+ pFilteringTable->num_rules = 1;
+
+ memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy));
+ flt_rule.status = -1;
+
+ flt_rule.rule.retain_hdr = 1;
+ flt_rule.rule.to_uc = 0;
+ flt_rule.rule.action = IPA_PASS_TO_EXCEPTION;
+ flt_rule.rule.eq_attrib_type = 0;
+
+ memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib));
+ flt_rule.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
+ flt_rule.rule.attrib.u.v6.dst_addr[0] = IPACM_Wan::backhaul_ipv6_prefix[0];
+ flt_rule.rule.attrib.u.v6.dst_addr[1] = IPACM_Wan::backhaul_ipv6_prefix[1];
+ flt_rule.rule.attrib.u.v6.dst_addr[2] = 0x0;
+ flt_rule.rule.attrib.u.v6.dst_addr[3] = 0x0;
+ flt_rule.rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
+ flt_rule.rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
+ flt_rule.rule.attrib.u.v6.dst_addr_mask[2] = 0x0;
+ flt_rule.rule.attrib.u.v6.dst_addr_mask[3] = 0x0;
+
+ flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v6[offset];
+ memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy));
+
+ if (false == m_filtering.ModifyFilteringRule(pFilteringTable))
+ {
+ IPACMERR("Failed to modify wlan guest AP IPv6 filtering rules.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ /* copy filter rule hdls */
+ wlan_guest_ap_flt_rule_hdl_v6 = pFilteringTable->rules[0].rule_hdl;
+
+fail:
+ if(pFilteringTable != NULL)
+ {
+ free(pFilteringTable);
+ }
+ return res;
+}
+
+int IPACM_Wlan::eth_bridge_handle_dummy_wlan_client_flt_rule(ipa_ip_type iptype)
+{
+ int i, offset;
+ if(wlan_ap_index == 0)
+ {
+ if(iptype == IPA_IP_v4)
+ {
+ offset = IPV4_DEFAULT_FILTERTING_RULES + IPACM_Iface::ipacmcfg->ipa_num_private_subnet;
+ for(i=0; i<IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; i++)
+ {
+ self_client_flt_rule_hdl_v4[i].rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v4[offset+i];
+ self_client_flt_rule_hdl_v4[i].valid = true;
+ }
+ }
+ else
+ {
+ offset = 1;
+ for(i=0; i<IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; i++)
+ {
+ self_client_flt_rule_hdl_v6[i].rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v6[offset+i];
+ self_client_flt_rule_hdl_v6[i].valid = true;
+ }
+ }
+ IPACMDBG_H("Get %d flt rule hdls for wlan clients ip type: %d.\n", IPA_LAN_TO_LAN_MAX_WLAN_CLIENT, iptype);
+ }
+ return IPACM_SUCCESS;
+}
+
+int IPACM_Wlan::eth_bridge_handle_dummy_usb_client_flt_rule(ipa_ip_type iptype)
+{
+ int i, offset;
+ if(wlan_ap_index == 0)
+ {
+ if(iptype == IPA_IP_v4)
+ {
+ offset = IPV4_DEFAULT_FILTERTING_RULES + IPACM_Iface::ipacmcfg->ipa_num_private_subnet + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT;
+ for(i=0; i<IPA_LAN_TO_LAN_MAX_USB_CLIENT; i++)
+ {
+ usb_client_flt_rule_hdl_v4[i].rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v4[offset+i];
+ usb_client_flt_rule_hdl_v4[i].valid = true;
+ }
+ }
+ else
+ {
+ offset = 1 + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT;
+ for(i=0; i<IPA_LAN_TO_LAN_MAX_USB_CLIENT; i++)
+ {
+ usb_client_flt_rule_hdl_v6[i].rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v6[offset+i];
+ usb_client_flt_rule_hdl_v6[i].valid = true;
+ }
+ }
+ IPACMDBG_H("Get %d flt rule hdls for usb clients ip type: %d.\n", IPA_LAN_TO_LAN_MAX_USB_CLIENT, iptype);
+ }
+ return IPACM_SUCCESS;
+}
+
+int IPACM_Wlan::eth_bridge_add_usb_client_flt_rule(uint8_t* mac, ipa_ip_type iptype)
+{
+ int i, len, res = IPACM_SUCCESS, client_position;
+ struct ipa_flt_rule_mdfy flt_rule;
+ struct ipa_ioc_mdfy_flt_rule* pFilteringTable = NULL;
+ bool client_is_found = false;
+
+ 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;
+ }
+ if(IPACM_Lan::wlan_to_usb_hdr_proc_ctx.valid == false)
+ {
+ IPACMDBG_H("WLAN to USB hdr proc ctx has not been set, don't add USB client specific flt rule.\n");
+ return IPACM_FAILURE;
+ }
+
+ for(i=0; i<num_usb_client; i++)
+ {
+ if(memcmp(eth_bridge_usb_client_flt_info[i].mac, mac, sizeof(eth_bridge_usb_client_flt_info[i].mac)) == 0)
+ {
+ client_is_found = true;
+ client_position = i;
+ if( (iptype == IPA_IP_v4 && eth_bridge_usb_client_flt_info[i].flt_rule_set_v4 == true)
+ || (iptype == IPA_IP_v6 && eth_bridge_usb_client_flt_info[i].flt_rule_set_v6 == true))
+ {
+ IPACMDBG_H("Flt rule for iptype %d has been set.\n", iptype);
+ return IPACM_SUCCESS;
+ }
+ break;
+ }
+ }
+
+ if(client_is_found == false && num_usb_client == IPA_LAN_TO_LAN_MAX_USB_CLIENT)
+ {
+ IPACMDBG_H("The usb client flt table is already full.\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);
+
+ IPACMDBG_H("Receive USB client MAC 0x%02x%02x%02x%02x%02x%02x.\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+
+ /* add mac based rule on flt table */
+ pFilteringTable->commit = 1;
+ pFilteringTable->ip = iptype;
+ pFilteringTable->num_rules = 1;
+
+ /* point to USB-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(iptype == IPA_IP_v4)
+ {
+ if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_usb_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_usb_wlan_v4.hdl;
+ IPACMDBG_H("WLAN->USB IPv4 filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_usb_wlan_v4.name);
+ }
+ else
+ {
+ if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_usb_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_usb_wlan_v6.hdl;
+ IPACMDBG_H("WLAN->USB IPv6 filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_usb_wlan_v6.name);
+ }
+
+ memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib));
+ 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(iptype == IPA_IP_v4)
+ {
+ for(i=0; i<IPA_LAN_TO_LAN_MAX_USB_CLIENT; i++)
+ {
+ if(usb_client_flt_rule_hdl_v4[i].valid == true)
+ {
+ flt_rule.rule_hdl = usb_client_flt_rule_hdl_v4[i].rule_hdl;
+ usb_client_flt_rule_hdl_v4[i].valid = false;
+ break;
+ }
+ }
+ if(i == IPA_LAN_TO_LAN_MAX_USB_CLIENT)
+ {
+ IPACMDBG_H("Cannot find a valid flt rule hdl.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ }
+ else
+ {
+ for(i=0; i<IPA_LAN_TO_LAN_MAX_USB_CLIENT; i++)
+ {
+ if(usb_client_flt_rule_hdl_v6[i].valid == true)
+ {
+ flt_rule.rule_hdl = usb_client_flt_rule_hdl_v6[i].rule_hdl;
+ usb_client_flt_rule_hdl_v6[i].valid = false;
+ break;
+ }
+ }
+ if(i == IPA_LAN_TO_LAN_MAX_USB_CLIENT)
+ {
+ IPACMDBG_H("Cannot find a valid flt rule hdl.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ }
+
+ memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy));
+ if (false == m_filtering.ModifyFilteringRule(pFilteringTable))
+ {
+ IPACMERR("Failed to add wlan client filtering rules.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ if(client_is_found == false)
+ {
+ client_position = num_usb_client;
+ num_usb_client++;
+ }
+
+ memcpy(eth_bridge_usb_client_flt_info[client_position].mac, mac, sizeof(eth_bridge_usb_client_flt_info[client_position].mac));
+ if(iptype == IPA_IP_v4)
+ {
+ eth_bridge_usb_client_flt_info[client_position].flt_rule_set_v4 = true;
+ eth_bridge_usb_client_flt_info[client_position].flt_rule_hdl_v4 = usb_client_flt_rule_hdl_v4[i].rule_hdl;
+ }
+ else
+ {
+ eth_bridge_usb_client_flt_info[client_position].flt_rule_set_v6 = true;
+ eth_bridge_usb_client_flt_info[client_position].flt_rule_hdl_v6 = usb_client_flt_rule_hdl_v6[i].rule_hdl;
+ }
+
+fail:
+ if(pFilteringTable == NULL)
+ {
+ free(pFilteringTable);
+ }
+ return res;
+}
+
+int IPACM_Wlan::eth_bridge_del_usb_client_flt_rule(uint8_t* mac)
+{
+ if(mac == NULL)
+ {
+ IPACMERR("Client MAC address is empty.\n");
+ return IPACM_FAILURE;
+ }
+
+ IPACMDBG_H("Receive USB client MAC 0x%02x%02x%02x%02x%02x%02x.\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+
+ int i, j, res = IPACM_SUCCESS;
+ for(i=0; i<num_usb_client; i++)
+ {
+ if(memcmp(eth_bridge_usb_client_flt_info[i].mac, mac, sizeof(eth_bridge_usb_client_flt_info[i].mac)) == 0)
+ {
+ break;
+ }
+ }
+
+ if(i == num_usb_client)
+ {
+ IPACMERR("Do not find the usb client.\n");
+ return IPACM_FAILURE;
+ }
+
+ if(eth_bridge_usb_client_flt_info[i].flt_rule_set_v4 == true)
+ {
+ if(reset_to_dummy_flt_rule(IPA_IP_v4, eth_bridge_usb_client_flt_info[i].flt_rule_hdl_v4) == IPACM_SUCCESS)
+ {
+ for(j=0; j<IPA_LAN_TO_LAN_MAX_USB_CLIENT; j++)
+ {
+ if(usb_client_flt_rule_hdl_v4[j].rule_hdl == eth_bridge_usb_client_flt_info[i].flt_rule_hdl_v4)
+ {
+ usb_client_flt_rule_hdl_v4[j].valid = true;
+ break;
+ }
+ }
+ if(j == IPA_LAN_TO_LAN_MAX_USB_CLIENT)
+ {
+ IPACMERR("Not finding the rule handle in handle pool.\n");
+ return IPACM_FAILURE;
+ }
+ }
+ else
+ {
+ IPACMERR("Failed to delete the usb client specific flt rule.\n");
+ return IPACM_FAILURE;
+ }
+ }
+ if(eth_bridge_usb_client_flt_info[i].flt_rule_set_v6 == true)
+ {
+ if(reset_to_dummy_flt_rule(IPA_IP_v6, eth_bridge_usb_client_flt_info[i].flt_rule_hdl_v6) == IPACM_SUCCESS)
+ {
+ for(j=0; j<IPA_LAN_TO_LAN_MAX_USB_CLIENT; j++)
+ {
+ if(usb_client_flt_rule_hdl_v6[j].rule_hdl == eth_bridge_usb_client_flt_info[i].flt_rule_hdl_v6)
+ {
+ usb_client_flt_rule_hdl_v6[j].valid = true;
+ break;
+ }
+ }
+ if(j == IPA_LAN_TO_LAN_MAX_USB_CLIENT)
+ {
+ IPACMERR("Not finding the rule handle in handle pool.\n");
+ return IPACM_FAILURE;
+ }
+ }
+ else
+ {
+ IPACMERR("Failed to delete the usb client specific flt rule.\n");
+ return IPACM_FAILURE;
+ }
+ }
+
+ for(j=i+1; j<num_usb_client; j++)
+ {
+ memcpy(&(eth_bridge_usb_client_flt_info[j-1]), &(eth_bridge_usb_client_flt_info[j]), sizeof(eth_bridge_client_flt_info));
+ }
+ memset(&(eth_bridge_usb_client_flt_info[num_usb_client-1]), 0, sizeof(eth_bridge_client_flt_info));
+ num_usb_client--;
+
+ return res;
+}
+
+int IPACM_Wlan::eth_bridge_add_self_client_flt_rule(uint8_t* mac, ipa_ip_type iptype)
+{
+ int i, len, res = IPACM_SUCCESS, client_position;
+ struct ipa_flt_rule_mdfy flt_rule;
+ struct ipa_ioc_mdfy_flt_rule* pFilteringTable = NULL;
+ bool client_is_found = false;
+
+ 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;
+ }
+ if(IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.valid == false)
+ {
+ IPACMDBG_H("WLAN to WLAN hdr proc ctx has not been set, don't add WLAN client specific flt rule.\n");
+ return IPACM_FAILURE;
+ }
+
+ for(i=0; i<wlan_client_flt_info_count; i++)
+ {
+ if(memcmp(eth_bridge_wlan_client_flt_info[i].mac, mac, sizeof(eth_bridge_wlan_client_flt_info[i].mac)) == 0)
+ {
+ client_is_found = true;
+ client_position = i;
+ if( (iptype == IPA_IP_v4 && eth_bridge_wlan_client_flt_info[i].flt_rule_set_v4 == true)
+ || (iptype == IPA_IP_v6 && eth_bridge_wlan_client_flt_info[i].flt_rule_set_v6 == true))
+ {
+ IPACMDBG_H("Flt rule for iptype %d has been set.\n", iptype);
+ return IPACM_SUCCESS;
+ }
+ break;
+ }
+ }
+
+ if(client_is_found == false && wlan_client_flt_info_count == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT)
+ {
+ IPACMDBG_H("The wlan client flt table is already full.\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);
+
+ 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]);
+
+ /* add mac based rule on IPv4 table */
+ pFilteringTable->commit = 1;
+ pFilteringTable->ip = iptype;
+ pFilteringTable->num_rules = 1;
+
+ /* point to USB-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(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 IPv4 filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v6.name);
+ }
+
+ 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
+ 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(iptype == IPA_IP_v4)
+ {
+ for(i=0; i<IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; i++)
+ {
+ if(self_client_flt_rule_hdl_v4[i].valid == true)
+ {
+ flt_rule.rule_hdl = self_client_flt_rule_hdl_v4[i].rule_hdl;
+ self_client_flt_rule_hdl_v4[i].valid = false;
+ break;
+ }
+ }
+ if(i == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT)
+ {
+ IPACMDBG_H("Cannot find a valid flt rule hdl.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ }
+ else
+ {
+ for(i=0; i<IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; i++)
+ {
+ if(self_client_flt_rule_hdl_v6[i].valid == true)
+ {
+ flt_rule.rule_hdl = self_client_flt_rule_hdl_v6[i].rule_hdl;
+ self_client_flt_rule_hdl_v6[i].valid = false;
+ break;
+ }
+ }
+ if(i == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT)
+ {
+ IPACMDBG_H("Cannot find a valid flt rule hdl.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ }
+
+ memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy));
+ if (false == m_filtering.ModifyFilteringRule(pFilteringTable))
+ {
+ IPACMERR("Failed to add self client filtering rules.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ if(client_is_found == false)
+ {
+ client_position = wlan_client_flt_info_count;
+ wlan_client_flt_info_count++;
+ }
+
+ memcpy(eth_bridge_wlan_client_flt_info[client_position].mac, mac, sizeof(eth_bridge_wlan_client_flt_info[client_position].mac));
+ if(iptype == IPA_IP_v4)
+ {
+ eth_bridge_wlan_client_flt_info[client_position].flt_rule_set_v4 = true;
+ eth_bridge_wlan_client_flt_info[client_position].flt_rule_hdl_v4 = self_client_flt_rule_hdl_v4[i].rule_hdl;
+ }
+ else
+ {
+ eth_bridge_wlan_client_flt_info[client_position].flt_rule_set_v6 = true;
+ eth_bridge_wlan_client_flt_info[client_position].flt_rule_hdl_v6 = self_client_flt_rule_hdl_v6[i].rule_hdl;
+ }
+
+fail:
+ if(pFilteringTable == NULL)
+ {
+ free(pFilteringTable);
+ }
+ return res;
+}
+
+int IPACM_Wlan::eth_bridge_del_self_client_flt_rule(uint8_t* mac)
+{
+ if(mac == NULL)
+ {
+ IPACMERR("Client MAC address is empty.\n");
+ 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, j, res = IPACM_SUCCESS;
+ for(i=0; i<wlan_client_flt_info_count; i++)
+ {
+ if(memcmp(eth_bridge_wlan_client_flt_info[i].mac, mac, sizeof(eth_bridge_wlan_client_flt_info[i].mac)) == 0)
+ {
+ break;
+ }
+ }
+
+ if(i == wlan_client_flt_info_count)
+ {
+ IPACMERR("Do not find the wlan client.\n");
+ return IPACM_FAILURE;
+ }
+
+ if(eth_bridge_wlan_client_flt_info[i].flt_rule_set_v4 == true)
+ {
+ if(reset_to_dummy_flt_rule(IPA_IP_v4, eth_bridge_wlan_client_flt_info[i].flt_rule_hdl_v4) == IPACM_SUCCESS)
+ {
+ for(j=0; j<IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; j++)
+ {
+ if(self_client_flt_rule_hdl_v4[j].rule_hdl == eth_bridge_wlan_client_flt_info[i].flt_rule_hdl_v4)
+ {
+ self_client_flt_rule_hdl_v4[j].valid = true;
+ break;
+ }
+ }
+ if(j == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT)
+ {
+ IPACMERR("Not finding the rule handle in handle pool.\n");
+ return IPACM_FAILURE;
+ }
+ }
+ else
+ {
+ IPACMERR("Failed to delete the wlan client specific flt rule.\n");
+ return IPACM_FAILURE;
+ }
+ }
+ if(eth_bridge_wlan_client_flt_info[i].flt_rule_set_v6 == true)
+ {
+ if(reset_to_dummy_flt_rule(IPA_IP_v6, eth_bridge_wlan_client_flt_info[i].flt_rule_hdl_v6) == IPACM_SUCCESS)
+ {
+ for(j=0; j<IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; j++)
+ {
+ if(self_client_flt_rule_hdl_v6[j].rule_hdl == eth_bridge_wlan_client_flt_info[i].flt_rule_hdl_v6)
+ {
+ self_client_flt_rule_hdl_v6[j].valid = true;
+ break;
+ }
+ }
+ if(j == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT)
+ {
+ IPACMERR("Not finding the rule handle in handle pool.\n");
+ return IPACM_FAILURE;
+ }
+ }
+ else
+ {
+ IPACMERR("Failed to delete the wlan client specific flt rule.\n");
+ return IPACM_FAILURE;
+ }
+ }
+
+ for(j=i+1; j<wlan_client_flt_info_count; j++)
+ {
+ memcpy(&(eth_bridge_wlan_client_flt_info[j-1]), &(eth_bridge_wlan_client_flt_info[j]), sizeof(eth_bridge_client_flt_info));
+ }
+ memset(&(eth_bridge_wlan_client_flt_info[wlan_client_flt_info_count-1]), 0, sizeof(eth_bridge_client_flt_info));
+ wlan_client_flt_info_count--;
+
+ return res;
+}
+
+int IPACM_Wlan::eth_bridge_install_cache_usb_client_flt_rule(ipa_ip_type iptype)
+{
+ int i;
+
+ IPACMDBG_H("There are %d usb clients cached.\n", IPACM_Lan::num_usb_client);
+ for(i=0; i<IPACM_Lan::num_usb_client; i++)
+ {
+ eth_bridge_add_usb_client_flt_rule(IPACM_Lan::eth_bridge_usb_client[i].mac, iptype);
+ }
+ return IPACM_SUCCESS;
+}
+
+int IPACM_Wlan::eth_bridge_install_cache_wlan_client_flt_rule(ipa_ip_type iptype)
+{
+ int i;
+
+ IPACMDBG_H("There are %d wlan clients cached.\n", IPACM_Lan::num_wlan_client);
+ for(i=0; i<IPACM_Lan::num_wlan_client; i++)
+ {
+ eth_bridge_add_self_client_flt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac, iptype);
+ }
+ return IPACM_SUCCESS;
+}
+
+int IPACM_Wlan::eth_bridge_add_wlan_client_rt_rule(uint8_t* mac, eth_bridge_src_iface src, ipa_ip_type iptype)
+{
+ if(tx_prop == NULL)
+ {
+ IPACMDBG_H("Tx prop is empty, not adding routing rule.\n");
+ return IPACM_SUCCESS;
+ }
+ if(mac == NULL)
+ {
+ IPACMERR("Client MAC address is empty.\n");
+ return IPACM_FAILURE;
+ }
+ if(iptype == IPA_IP_v4)
+ {
+ if( (src == SRC_WLAN && wlan_client_rt_from_wlan_info_count_v4 == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT)
+ || (src == SRC_USB && wlan_client_rt_from_usb_info_count_v4 == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT))
+ {
+ IPACMDBG_H("WLAN client number has reached maximum.\n");
+ return IPACM_FAILURE;
+ }
+ }
+ else
+ {
+ if( (src == SRC_WLAN && wlan_client_rt_from_wlan_info_count_v6 == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT)
+ || (src == SRC_USB && wlan_client_rt_from_usb_info_count_v6 == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT))
+ {
+ IPACMDBG_H("WLAN client number has reached maximum.\n");
+ return IPACM_FAILURE;
+ }
+ }
+ if( (src == SRC_WLAN && IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.valid == false)
+ || (src == SRC_USB && IPACM_Lan::usb_to_wlan_hdr_proc_ctx.valid == false) )
+ {
+ IPACMDBG_H("Hdr proc ctx has not been set for source %d, don't add WLAN client routing rule.\n", src);
+ 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;
+ int position, num_rt_rule;
+
+ if(src == SRC_WLAN)
+ {
+ if(iptype == IPA_IP_v4)
+ {
+ for(i=0; i<wlan_client_rt_from_wlan_info_count_v4; i++)
+ {
+ if(memcmp(eth_bridge_get_client_rt_info_ptr(i, SRC_WLAN, iptype)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, SRC_WLAN, iptype)->mac)) == 0)
+ {
+ IPACMDBG_H("The client's routing rule was added before.\n");
+ return IPACM_SUCCESS;
+ }
+ }
+ memcpy(eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_wlan_info_count_v4, src, iptype)->mac, mac,
+ sizeof(eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_wlan_info_count_v4, src, iptype)->mac));
+ }
+ else
+ {
+ for(i=0; i<wlan_client_rt_from_wlan_info_count_v6; i++)
+ {
+ if(memcmp(eth_bridge_get_client_rt_info_ptr(i, SRC_WLAN, iptype)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, SRC_WLAN, iptype)->mac)) == 0)
+ {
+ IPACMDBG_H("The client's routing rule was added before.\n");
+ return IPACM_SUCCESS;
+ }
+ }
+ memcpy(eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_wlan_info_count_v6, src, iptype)->mac, mac,
+ sizeof(eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_wlan_info_count_v6, src, iptype)->mac));
+ }
+ }
+ else
+ {
+ if(iptype == IPA_IP_v4)
+ {
+ for(i=0; i<wlan_client_rt_from_usb_info_count_v4; i++)
+ {
+ if(memcmp(eth_bridge_get_client_rt_info_ptr(i, SRC_USB, iptype)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, SRC_USB, iptype)->mac)) == 0)
+ {
+ IPACMDBG_H("The client's routing rule was added before.\n");
+ return IPACM_SUCCESS;
+ }
+ }
+ memcpy(eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_usb_info_count_v4, src, iptype)->mac, mac,
+ sizeof(eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_usb_info_count_v4, src, iptype)->mac));
+ }
+ else
+ {
+ for(i=0; i<wlan_client_rt_from_usb_info_count_v6; i++)
+ {
+ if(memcmp(eth_bridge_get_client_rt_info_ptr(i, SRC_USB, iptype)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, SRC_USB, iptype)->mac)) == 0)
+ {
+ IPACMDBG_H("The client's routing rule was added before.\n");
+ return IPACM_SUCCESS;
+ }
+ }
+ memcpy(eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_usb_info_count_v6, src, iptype)->mac, mac,
+ sizeof(eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_usb_info_count_v6, src, iptype)->mac));
+ }
+ }
+
+ if(iptype == IPA_IP_v4)
+ {
+ num_rt_rule = each_client_rt_rule_count_v4;
+ }
+ else
+ {
+ num_rt_rule = each_client_rt_rule_count_v6;
+ }
+
+ len = sizeof(ipa_ioc_add_rt_rule) + num_rt_rule * sizeof(ipa_rt_rule_add);
+ rt_rule_table = (ipa_ioc_add_rt_rule*)malloc(len);
+ if(rt_rule_table == NULL)
+ {
+ IPACMERR("Failed to allocate memory.\n");
+ return IPACM_FAILURE;
+ }
+ memset(rt_rule_table, 0, len);
+
+ rt_rule_table->commit = 1;
+ rt_rule_table->ip = iptype;
+ rt_rule_table->num_rules = num_rt_rule;
+ if(src == SRC_WLAN)
+ {
+ if(iptype == IPA_IP_v4)
+ {
+ strncpy(rt_rule_table->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v4.name, sizeof(rt_rule_table->rt_tbl_name));
+ }
+ else
+ {
+ strncpy(rt_rule_table->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v6.name, sizeof(rt_rule_table->rt_tbl_name));
+ }
+ }
+ else
+ {
+ if(iptype == IPA_IP_v4)
+ {
+ strncpy(rt_rule_table->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_usb_wlan_v4.name, sizeof(rt_rule_table->rt_tbl_name));
+ }
+ else
+ {
+ strncpy(rt_rule_table->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_usb_wlan_v6.name, sizeof(rt_rule_table->rt_tbl_name));
+ }
+ }
+
+ memset(&rt_rule, 0, sizeof(ipa_rt_rule_add));
+ rt_rule.at_rear = false;
+ rt_rule.status = -1;
+ rt_rule.rt_rule_hdl = -1;
+
+ rt_rule.rule.hdr_hdl = 0;
+ if(src == SRC_WLAN)
+ {
+ rt_rule.rule.hdr_proc_ctx_hdl = IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.proc_ctx_hdl;
+ }
+ else
+ {
+ rt_rule.rule.hdr_proc_ctx_hdl = IPACM_Lan::usb_to_wlan_hdr_proc_ctx.proc_ctx_hdl;
+ }
+ position = 0;
+ for(i=0; i<iface_query->num_tx_props; i++)
+ {
+ if(tx_prop->tx[i].ip == iptype)
+ {
+ if(position >= num_rt_rule)
+ {
+ IPACMERR("Number of routing rules already exceeds limit.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ rt_rule.rule.dst = tx_prop->tx[i].dst_pipe;
+ memcpy(&rt_rule.rule.attrib, &tx_prop->tx[i].attrib, sizeof(rt_rule.rule.attrib));
+ if(src == SRC_WLAN) //src is WLAN means packet is from WLAN
+ {
+ if(IPACM_Lan::wlan_hdr_type == IPA_HDR_L2_ETHERNET_II)
+ {
+ rt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II;
+ }
+ else
+ {
+ rt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3;
+ }
+ }
+ else //packet is from USB
+ {
+ if(IPACM_Lan::usb_hdr_type == IPA_HDR_L2_ETHERNET_II)
+ {
+ rt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II;
+ }
+ else
+ {
+ rt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3;
+ }
+ }
+ memcpy(rt_rule.rule.attrib.dst_mac_addr, mac, sizeof(rt_rule.rule.attrib.dst_mac_addr));
+ memset(rt_rule.rule.attrib.dst_mac_addr_mask, 0xFF, sizeof(rt_rule.rule.attrib.dst_mac_addr_mask));
+
+ memcpy(&(rt_rule_table->rules[position]), &rt_rule, sizeof(rt_rule_table->rules[position]));
+ position++;
+ }
+ }
+
+ if(false == m_routing.AddRoutingRule(rt_rule_table))
+ {
+ IPACMERR("Routing rule addition failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ else
+ {
+ if(src == SRC_WLAN)
+ {
+ for(i=0; i<num_rt_rule; i++)
+ {
+ if(iptype == IPA_IP_v4)
+ {
+ eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_wlan_info_count_v4, src, iptype)->rt_rule_hdl[i] = rt_rule_table->rules[i].rt_rule_hdl;
+ }
+ else
+ {
+ eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_wlan_info_count_v6, src, iptype)->rt_rule_hdl[i] = rt_rule_table->rules[i].rt_rule_hdl;
+ }
+ }
+ if(iptype == IPA_IP_v4)
+ {
+ wlan_client_rt_from_wlan_info_count_v4++;
+ IPACMDBG_H("Now the number of IPv4 rt rule on wlan-wlan rt table is %d.\n", wlan_client_rt_from_wlan_info_count_v4);
+ }
+ else
+ {
+ wlan_client_rt_from_wlan_info_count_v6++;
+ IPACMDBG_H("Now the number of IPv6 rt rule on wlan-wlan rt table is %d.\n", wlan_client_rt_from_wlan_info_count_v6);
+ }
+ }
+ else
+ {
+ for(i=0; i<num_rt_rule; i++)
+ {
+ if(iptype == IPA_IP_v4)
+ {
+ eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_usb_info_count_v4, src, iptype)->rt_rule_hdl[i] = rt_rule_table->rules[i].rt_rule_hdl;
+ }
+ else
+ {
+ eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_usb_info_count_v6, src, iptype)->rt_rule_hdl[i] = rt_rule_table->rules[i].rt_rule_hdl;
+ }
+ }
+ if(iptype == IPA_IP_v4)
+ {
+ wlan_client_rt_from_usb_info_count_v4++;
+ IPACMDBG_H("Now the number of IPv4 rt rule on usb-wlan rt table is %d.\n", wlan_client_rt_from_usb_info_count_v4);
+ }
+ else
+ {
+ wlan_client_rt_from_usb_info_count_v6++;
+ IPACMDBG_H("Now the number of IPv6 rt rule on usb-wlan rt table is %d.\n", wlan_client_rt_from_usb_info_count_v6);
+ }
+ }
+ }
+
+fail:
+ if(rt_rule_table != NULL)
+ {
+ free(rt_rule_table);
+ }
+ return res;
+}
+
+int IPACM_Wlan::eth_bridge_del_wlan_client_rt_rule(uint8_t* mac, eth_bridge_src_iface src)
+{
+ if(tx_prop == NULL)
+ {
+ IPACMDBG_H("Tx prop is empty, not deleting routing rule.\n");
+ return IPACM_SUCCESS;
+ }
+ if(mac == NULL)
+ {
+ IPACMERR("Client MAC address is empty.\n");
+ 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, position;
+
+ /* first delete the rt rules from IPv4 rt table*/
+ if(src == SRC_WLAN)
+ {
+ for(i=0; i<wlan_client_rt_from_wlan_info_count_v4; i++)
+ {
+ if(memcmp(eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v4)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v4)->mac)) == 0)
+ {
+ position = i;
+ IPACMDBG_H("The client is found at position %d.\n", position);
+ break;
+ }
+ }
+ if(i == wlan_client_rt_from_wlan_info_count_v4)
+ {
+ IPACMERR("The client is not found.\n");
+ return IPACM_FAILURE;
+ }
+ }
+ else
+ {
+ for(i=0; i<wlan_client_rt_from_usb_info_count_v4; i++)
+ {
+ if(memcmp(eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v4)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v4)->mac)) == 0)
+ {
+ position = i;
+ IPACMDBG_H("The client is found at position %d.\n", position);
+ break;
+ }
+ }
+ if(i == wlan_client_rt_from_usb_info_count_v4)
+ {
+ IPACMERR("The client is not found.\n");
+ return IPACM_FAILURE;
+ }
+ }
+
+ for(i=0; i<each_client_rt_rule_count_v4; i++)
+ {
+ if(m_routing.DeleteRoutingHdl(eth_bridge_get_client_rt_info_ptr(position, src, IPA_IP_v4)->rt_rule_hdl[i], IPA_IP_v4) == false)
+ {
+ IPACMERR("Failed to delete routing rule %d.\n", i);
+ return IPACM_FAILURE;
+ }
+ }
+
+ if(src == SRC_WLAN)
+ {
+ for(i=position+1; i<wlan_client_rt_from_wlan_info_count_v4; i++)
+ {
+ memcpy(eth_bridge_get_client_rt_info_ptr(i-1, src, IPA_IP_v4), eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v4), client_rt_info_size_v4);
+ }
+ memset(eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_wlan_info_count_v4-1, src, IPA_IP_v4), 0, client_rt_info_size_v4);
+ wlan_client_rt_from_wlan_info_count_v4--;
+ IPACMDBG_H("Now the number of IPv4 rt rule from wlan info is %d.\n", wlan_client_rt_from_wlan_info_count_v4);
+ }
+ else
+ {
+ for(i=position+1; i<wlan_client_rt_from_usb_info_count_v4; i++)
+ {
+ memcpy(eth_bridge_get_client_rt_info_ptr(i-1, src, IPA_IP_v4), eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v4), client_rt_info_size_v4);
+ }
+ memset(eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_usb_info_count_v4-1, src, IPA_IP_v4), 0, client_rt_info_size_v4);
+ wlan_client_rt_from_usb_info_count_v4--;
+ IPACMDBG_H("Now the number of IPv4 rt rule from usb info is %d.\n", wlan_client_rt_from_usb_info_count_v4);
+ }
+
+ /*delete rt rules from IPv6 rt table */
+ if(src == SRC_WLAN)
+ {
+ for(i=0; i<wlan_client_rt_from_wlan_info_count_v6; i++)
+ {
+ if(memcmp(eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v6)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v6)->mac)) == 0)
+ {
+ position = i;
+ IPACMDBG_H("The client is found at position %d.\n", position);
+ break;
+ }
+ }
+ if(i == wlan_client_rt_from_wlan_info_count_v6)
+ {
+ IPACMERR("The client is not found.\n");
+ return IPACM_FAILURE;
+ }
+ }
+ else
+ {
+ for(i=0; i<wlan_client_rt_from_usb_info_count_v6; i++)
+ {
+ if(memcmp(eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v6)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v6)->mac)) == 0)
+ {
+ position = i;
+ IPACMDBG_H("The client is found at position %d.\n", position);
+ break;
+ }
+ }
+ if(i == wlan_client_rt_from_usb_info_count_v6)
+ {
+ IPACMERR("The client is not found.\n");
+ return IPACM_FAILURE;
+ }
+ }
+
+ for(i=0; i<each_client_rt_rule_count_v6; i++)
+ {
+ if(m_routing.DeleteRoutingHdl(eth_bridge_get_client_rt_info_ptr(position, src, IPA_IP_v6)->rt_rule_hdl[i], IPA_IP_v6) == false)
+ {
+ IPACMERR("Failed to delete routing rule %d.\n", i);
+ return IPACM_FAILURE;
+ }
+ }
+
+ if(src == SRC_WLAN)
+ {
+ for(i=position+1; i<wlan_client_rt_from_wlan_info_count_v6; i++)
+ {
+ memcpy(eth_bridge_get_client_rt_info_ptr(i-1, src, IPA_IP_v6), eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v6), client_rt_info_size_v6);
+ }
+ memset(eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_wlan_info_count_v6-1, src, IPA_IP_v6), 0, client_rt_info_size_v6);
+ wlan_client_rt_from_wlan_info_count_v6--;
+ IPACMDBG_H("Now the number of IPv6 rt rule from wlan info is %d.\n", wlan_client_rt_from_wlan_info_count_v6);
+ }
+ else
+ {
+ for(i=position+1; i<wlan_client_rt_from_usb_info_count_v6; i++)
+ {
+ memcpy(eth_bridge_get_client_rt_info_ptr(i-1, src, IPA_IP_v6), eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v6), client_rt_info_size_v6);
+ }
+ memset(eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_usb_info_count_v6-1, src, IPA_IP_v6), 0, client_rt_info_size_v6);
+ wlan_client_rt_from_usb_info_count_v6--;
+ IPACMDBG_H("Now the number of IPv6 rt rule from usb info is %d.\n", wlan_client_rt_from_usb_info_count_v6);
+ }
+
+ return IPACM_SUCCESS;
+}
+
+eth_bridge_client_rt_info* IPACM_Wlan::eth_bridge_get_client_rt_info_ptr(uint8_t index, eth_bridge_src_iface src, ipa_ip_type iptype)
+{
+ void* result;
+ if(src == SRC_WLAN)
+ {
+ if(iptype == IPA_IP_v4)
+ {
+ result = (void*)((void*)eth_bridge_wlan_client_rt_from_wlan_info_v4 + index * client_rt_info_size_v4);
+ }
+ else
+ {
+ result = (void*)((void*)eth_bridge_wlan_client_rt_from_wlan_info_v6 + index * client_rt_info_size_v6);
+ }
+ }
+ else
+ {
+ if(iptype == IPA_IP_v4)
+ {
+ result = (void*)((void*)eth_bridge_wlan_client_rt_from_usb_info_v4 + index * client_rt_info_size_v4);
+ }
+ else
+ {
+ result = (void*)((void*)eth_bridge_wlan_client_rt_from_usb_info_v6 + index * client_rt_info_size_v6);
+ }
+ }
+ return (eth_bridge_client_rt_info*)result;
+}
+
+void IPACM_Wlan::eth_bridge_add_wlan_client(uint8_t* mac, int if_num)
+{
+ if(IPACM_Lan::num_wlan_client == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT)
+ {
+ IPACMDBG_H("WLAN client table is already full.\n");
+ return;
+ }
+
+ if(mac == NULL)
+ {
+ IPACMERR("Mac address is empty.\n");
+ return;
+ }
+
+ memcpy(IPACM_Lan::eth_bridge_wlan_client[IPACM_Lan::num_wlan_client].mac, mac, sizeof(IPACM_Lan::eth_bridge_wlan_client[IPACM_Lan::num_wlan_client].mac));
+ IPACM_Lan::eth_bridge_wlan_client[IPACM_Lan::num_wlan_client].ipa_if_num = if_num;
+ IPACM_Lan::num_wlan_client++;
+ return;
+}
+
+void IPACM_Wlan::eth_bridge_del_wlan_client(uint8_t* mac)
+{
+ if(mac == NULL)
+ {
+ IPACMERR("Mac address is empty.\n");
+ return;
+ }
+
+ int i, j;
+ for(i=0; i<IPACM_Lan::num_wlan_client; i++)
+ {
+ if(memcmp(IPACM_Lan::eth_bridge_wlan_client[i].mac, mac, sizeof(IPACM_Lan::eth_bridge_wlan_client[i].mac)) == 0)
+ {
+ IPACMDBG_H("Found WLAN client at position %d.\n", i);
+ break;
+ }
+ }
+
+ if(i == IPACM_Lan::num_wlan_client)
+ {
+ IPACMDBG_H("Not finding the WLAN client.\n");
+ return;
+ }
+
+ for(j=i+1; j<IPACM_Lan::num_wlan_client; j++)
+ {
+ memcpy(IPACM_Lan::eth_bridge_wlan_client[j-1].mac, IPACM_Lan::eth_bridge_wlan_client[j].mac, sizeof(IPACM_Lan::eth_bridge_wlan_client[j].mac));
+ IPACM_Lan::eth_bridge_wlan_client[j-1].ipa_if_num = IPACM_Lan::eth_bridge_wlan_client[j].ipa_if_num;
+ }
+ IPACM_Lan::num_wlan_client--;
+ return;
+}
diff --git a/ipacm/src/Makefile.am b/ipacm/src/Makefile.am
index 254a569..4ee0a08 100644
--- a/ipacm/src/Makefile.am
+++ b/ipacm/src/Makefile.am
@@ -2,7 +2,7 @@
-I$(top_srcdir)/ipanat/inc \
${LIBXML_CFLAGS}
AM_CPPFLAGS += -Wall -Wundef -Wno-trigraphs
-AM_CPPFLAGS += -DDEBUG -g -DCT_OPT
+AM_CPPFLAGS += -DDEBUG -g -DFEATURE_ETH_BRIDGE_LE
ipacm_SOURCES = IPACM_Main.cpp \
IPACM_Conntrack_NATApp.cpp\