summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSkylar Chang <chiaweic@codeaurora.org>2015-10-27 12:21:18 -0700
committerSkylar Chang <chiaweic@codeaurora.org>2015-10-29 16:59:22 -0700
commit37e0de9d0171aa99ccfc13221f63e6eccd24374c (patch)
tree2a1f21c38f828868678b6309725ebffce96065fa
parent195d0070e8379786474285b5da8d04aee2c4bd24 (diff)
downloadipacfg-mgr-37e0de9d0171aa99ccfc13221f63e6eccd24374c.tar.gz
IPACM: change src mac to bridge0
In SW-exception, the src mac of the DL traffic to wifi-client will use bridge0's mac when device is in bridge mode however in IPA-HW path, the src mac of the DL traffic will use netdev's mac instead. This failed in layer2 security check with some special applications. The fix is to make src mac consistent in both SW-exception/IPA-HW cases. Change-Id: I2f248e2f3c265acfbecdeedac58e7e8dac36fec9
-rw-r--r--ipacm/inc/IPACM_Config.h6
-rw-r--r--ipacm/inc/IPACM_Defs.h1
-rw-r--r--ipacm/src/IPACM_Config.cpp2
-rw-r--r--ipacm/src/IPACM_IfaceManager.cpp20
-rw-r--r--ipacm/src/IPACM_Lan.cpp34
-rw-r--r--ipacm/src/IPACM_Netlink.cpp37
-rw-r--r--ipacm/src/IPACM_Wlan.cpp18
7 files changed, 104 insertions, 14 deletions
diff --git a/ipacm/inc/IPACM_Config.h b/ipacm/inc/IPACM_Config.h
index 54a4423..665b844 100644
--- a/ipacm/inc/IPACM_Config.h
+++ b/ipacm/inc/IPACM_Config.h
@@ -126,6 +126,12 @@ public:
/* Store SW-enable or not */
bool ipa_sw_rt_enable;
+ /* Store bridge mode or not */
+ bool ipa_bridge_enable;
+
+ /* Store bridge netdev mac */
+ uint8_t bridge_mac[IPA_MAC_ADDR_SIZE];
+
/* Store the flt rule count for each producer client*/
int flt_rule_count_v4[IPA_CLIENT_CONS - IPA_CLIENT_PROD];
int flt_rule_count_v6[IPA_CLIENT_CONS - IPA_CLIENT_PROD];
diff --git a/ipacm/inc/IPACM_Defs.h b/ipacm/inc/IPACM_Defs.h
index dcc55d0..b40d91d 100644
--- a/ipacm/inc/IPACM_Defs.h
+++ b/ipacm/inc/IPACM_Defs.h
@@ -194,6 +194,7 @@ typedef enum
IPA_HANDLE_WAN_DOWN_TETHER, /* 57 ipacm_event_iface_up_tehter */
IPA_HANDLE_WAN_UP_V6_TETHER, /* 58 ipacm_event_iface_up_tehter */
IPA_HANDLE_WAN_DOWN_V6_TETHER, /* 59 ipacm_event_iface_up_tehter */
+ IPA_BRIDGE_LINK_UP_EVENT, /* 60 ipacm_event_data_all */
IPACM_EVENT_MAX
} ipa_cm_event_id;
diff --git a/ipacm/src/IPACM_Config.cpp b/ipacm/src/IPACM_Config.cpp
index f7d764a..c718603 100644
--- a/ipacm/src/IPACM_Config.cpp
+++ b/ipacm/src/IPACM_Config.cpp
@@ -64,6 +64,7 @@ IPACM_Config::IPACM_Config()
ipa_nat_max_entries = 0;
ipa_nat_iface_entries = 0;
ipa_sw_rt_enable = false;
+ ipa_bridge_enable = false;
isMCC_Mode = false;
ipa_max_valid_rm_entry = 0;
@@ -88,6 +89,7 @@ IPACM_Config::IPACM_Config()
memset(flt_rule_count_v4, 0, (IPA_CLIENT_CONS - IPA_CLIENT_PROD)*sizeof(int));
memset(flt_rule_count_v6, 0, (IPA_CLIENT_CONS - IPA_CLIENT_PROD)*sizeof(int));
+ memset(bridge_mac, 0, IPA_MAC_ADDR_SIZE*sizeof(uint8_t));
IPACMDBG_H(" create IPACM_Config constructor\n");
return;
diff --git a/ipacm/src/IPACM_IfaceManager.cpp b/ipacm/src/IPACM_IfaceManager.cpp
index 3024ce6..59884ab 100644
--- a/ipacm/src/IPACM_IfaceManager.cpp
+++ b/ipacm/src/IPACM_IfaceManager.cpp
@@ -58,8 +58,10 @@ IPACM_IfaceManager::IPACM_IfaceManager()
IPACM_EvtDispatcher::registr(IPA_WLAN_AP_LINK_UP_EVENT, this); // register for wlan AP-iface
#ifndef FEATURE_IPA_ANDROID
IPACM_EvtDispatcher::registr(IPA_WLAN_STA_LINK_UP_EVENT, this); // register for wlan STA-iface
+ /* only MDM targets support device on bridge mode */
+ IPACM_EvtDispatcher::registr(IPA_BRIDGE_LINK_UP_EVENT, this); // register for IPA_BRIDGE_LINK_UP_EVENT event
#endif /* not defined(FEATURE_IPA_ANDROID)*/
- IPACM_EvtDispatcher::registr(IPA_USB_LINK_UP_EVENT, this); // register for wlan STA-iface
+ IPACM_EvtDispatcher::registr(IPA_USB_LINK_UP_EVENT, this); // register for USB-iface
IPACM_EvtDispatcher::registr(IPA_WAN_EMBMS_LINK_UP_EVENT, this); // register for wan eMBMS-iface
return;
}
@@ -69,6 +71,7 @@ void IPACM_IfaceManager::event_callback(ipa_cm_event_id event, void *param)
int ipa_interface_index;
ipacm_event_data_fid *evt_data = (ipacm_event_data_fid *)param;
ipacm_event_data_mac *StaData = (ipacm_event_data_mac *)param;
+ ipacm_event_data_all *data_all = (ipacm_event_data_all *)param;
ipacm_ifacemgr_data ifmgr_data = {0};
switch(event)
@@ -77,6 +80,21 @@ void IPACM_IfaceManager::event_callback(ipa_cm_event_id event, void *param)
IPACMDBG_H(" RESET IPACM_cfg \n");
IPACM_Iface::ipacmcfg->Init();
break;
+ case IPA_BRIDGE_LINK_UP_EVENT:
+ IPACMDBG_H(" Save the bridge0 mac info in IPACM_cfg \n");
+ ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data_all->if_index);
+ /* check if iface is bridge interface*/
+ if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name) == 0)
+ {
+ IPACM_Iface::ipacmcfg->ipa_bridge_enable = true;
+ memcpy(IPACM_Iface::ipacmcfg->bridge_mac,
+ data_all->mac_addr,
+ sizeof(IPACM_Iface::ipacmcfg->bridge_mac));
+ IPACMDBG_H("cached bridge0 MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
+ IPACM_Iface::ipacmcfg->bridge_mac[0], IPACM_Iface::ipacmcfg->bridge_mac[1], IPACM_Iface::ipacmcfg->bridge_mac[2],
+ IPACM_Iface::ipacmcfg->bridge_mac[3], IPACM_Iface::ipacmcfg->bridge_mac[4], IPACM_Iface::ipacmcfg->bridge_mac[5]);
+ }
+ break;
case IPA_LINK_UP_EVENT:
IPACMDBG_H("Recieved IPA_LINK_UP_EVENT event: link up %d: \n", evt_data->if_index);
ipa_interface_index = IPACM_Iface::iface_ipa_index_query(evt_data->if_index);
diff --git a/ipacm/src/IPACM_Lan.cpp b/ipacm/src/IPACM_Lan.cpp
index 40bbec5..eb7243b 100644
--- a/ipacm/src/IPACM_Lan.cpp
+++ b/ipacm/src/IPACM_Lan.cpp
@@ -1846,6 +1846,14 @@ int IPACM_Lan::handle_eth_hdr_init(uint8_t *mac_addr)
mac_addr,
IPA_MAC_ADDR_SIZE);
}
+ /* replace src mac to bridge mac_addr if any */
+ if (IPACM_Iface::ipacmcfg->ipa_bridge_enable)
+ {
+ memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst+IPA_MAC_ADDR_SIZE],
+ IPACM_Iface::ipacmcfg->bridge_mac,
+ IPA_MAC_ADDR_SIZE);
+ IPACMDBG_H("device is in bridge mode \n");
+ }
pHeaderDescriptor->commit = true;
pHeaderDescriptor->num_hdrs = 1;
@@ -1938,6 +1946,15 @@ int IPACM_Lan::handle_eth_hdr_init(uint8_t *mac_addr)
mac_addr,
IPA_MAC_ADDR_SIZE);
}
+ /* replace src mac to bridge mac_addr if any */
+ if (IPACM_Iface::ipacmcfg->ipa_bridge_enable)
+ {
+ memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst+IPA_MAC_ADDR_SIZE],
+ IPACM_Iface::ipacmcfg->bridge_mac,
+ IPA_MAC_ADDR_SIZE);
+ IPACMDBG_H("device is in bridge mode \n");
+ }
+
pHeaderDescriptor->commit = true;
pHeaderDescriptor->num_hdrs = 1;
@@ -2360,7 +2377,14 @@ int IPACM_Lan::handle_odu_hdr_init(uint8_t *mac_addr)
mac_addr,
IPA_MAC_ADDR_SIZE);
}
-
+ /* replace src mac to bridge mac_addr if any */
+ if (IPACM_Iface::ipacmcfg->ipa_bridge_enable)
+ {
+ memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst+IPA_MAC_ADDR_SIZE],
+ IPACM_Iface::ipacmcfg->bridge_mac,
+ IPA_MAC_ADDR_SIZE);
+ IPACMDBG_H("device is in bridge mode \n");
+ }
pHeaderDescriptor->commit = true;
pHeaderDescriptor->num_hdrs = 1;
@@ -2432,6 +2456,14 @@ int IPACM_Lan::handle_odu_hdr_init(uint8_t *mac_addr)
mac_addr,
IPA_MAC_ADDR_SIZE);
}
+ /* replace src mac to bridge mac_addr if any */
+ if (IPACM_Iface::ipacmcfg->ipa_bridge_enable)
+ {
+ memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst+IPA_MAC_ADDR_SIZE],
+ IPACM_Iface::ipacmcfg->bridge_mac,
+ IPA_MAC_ADDR_SIZE);
+ IPACMDBG_H("device is in bridge mode \n");
+ }
pHeaderDescriptor->commit = true;
pHeaderDescriptor->num_hdrs = 1;
diff --git a/ipacm/src/IPACM_Netlink.cpp b/ipacm/src/IPACM_Netlink.cpp
index a343e24..30295b1 100644
--- a/ipacm/src/IPACM_Netlink.cpp
+++ b/ipacm/src/IPACM_Netlink.cpp
@@ -1376,13 +1376,13 @@ static int ipa_nl_decode_nlmsg
IPACMDBG("\n GOT RTM_NEWNEIGH event (%s) ip %d\n",dev_name,msg_ptr->nl_neigh_info.attr_info.local_addr.ss_family);
}
- /* insert to command queue */
+ /* insert to command queue */
data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
if(data_all == NULL)
- {
+ {
IPACMERR("unable to allocate memory for event data_all\n");
return IPACM_FAILURE;
- }
+ }
memset(data_all, 0, sizeof(ipacm_event_data_all));
if(msg_ptr->nl_neigh_info.attr_info.local_addr.ss_family == AF_INET6)
@@ -1390,11 +1390,11 @@ static int ipa_nl_decode_nlmsg
IPACM_NL_REPORT_ADDR( " ", msg_ptr->nl_neigh_info.attr_info.local_addr);
IPACM_EVENT_COPY_ADDR_v6( data_all->ipv6_addr, msg_ptr->nl_neigh_info.attr_info.local_addr);
- data_all->ipv6_addr[0]=ntohl(data_all->ipv6_addr[0]);
- data_all->ipv6_addr[1]=ntohl(data_all->ipv6_addr[1]);
- data_all->ipv6_addr[2]=ntohl(data_all->ipv6_addr[2]);
- data_all->ipv6_addr[3]=ntohl(data_all->ipv6_addr[3]);
- data_all->iptype = IPA_IP_v6;
+ data_all->ipv6_addr[0]=ntohl(data_all->ipv6_addr[0]);
+ data_all->ipv6_addr[1]=ntohl(data_all->ipv6_addr[1]);
+ data_all->ipv6_addr[2]=ntohl(data_all->ipv6_addr[2]);
+ data_all->ipv6_addr[3]=ntohl(data_all->ipv6_addr[3]);
+ data_all->iptype = IPA_IP_v6;
}
else if (msg_ptr->nl_neigh_info.attr_info.local_addr.ss_family == AF_INET)
{
@@ -1420,13 +1420,26 @@ static int ipa_nl_decode_nlmsg
memcpy(data_all->mac_addr,
msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr.sa_data,
sizeof(data_all->mac_addr));
- evt_data.event = IPA_NEW_NEIGH_EVENT;
- data_all->if_index = msg_ptr->nl_neigh_info.metainfo.ndm_ifindex;
-
- IPACMDBG_H("posting IPA_NEW_NEIGH_EVENT (%s):index:%d ip-family: %d\n",
+ data_all->if_index = msg_ptr->nl_neigh_info.metainfo.ndm_ifindex;
+ /* Add support to replace src-mac as bridge0 mac */
+ if((msg_ptr->nl_neigh_info.metainfo.ndm_family == AF_BRIDGE) &&
+ (msg_ptr->nl_neigh_info.metainfo.ndm_state == NUD_PERMANENT))
+ {
+ /* Posting IPA_BRIDGE_LINK_UP_EVENT event */
+ evt_data.event = IPA_BRIDGE_LINK_UP_EVENT;
+ IPACMDBG_H("posting IPA_BRIDGE_LINK_UP_EVENT (%s):index:%d \n",
+ dev_name,
+ data_all->if_index);
+ }
+ else
+ {
+ /* Posting new_neigh events for all LAN/WAN clients */
+ evt_data.event = IPA_NEW_NEIGH_EVENT;
+ IPACMDBG_H("posting IPA_NEW_NEIGH_EVENT (%s):index:%d ip-family: %d\n",
dev_name,
data_all->if_index,
msg_ptr->nl_neigh_info.attr_info.local_addr.ss_family);
+ }
evt_data.evt_data = data_all;
IPACM_EvtDispatcher::PostEvt(&evt_data);
/* finish command queue */
diff --git a/ipacm/src/IPACM_Wlan.cpp b/ipacm/src/IPACM_Wlan.cpp
index 1971e90..97a6192 100644
--- a/ipacm/src/IPACM_Wlan.cpp
+++ b/ipacm/src/IPACM_Wlan.cpp
@@ -1782,6 +1782,15 @@ int IPACM_Wlan::handle_wlan_client_init_ex(ipacm_event_data_wlan_ex *data)
memcpy(&pHeaderDescriptor->hdr[0].hdr[data->attribs[i].offset],
get_client_memptr(wlan_client, num_wifi_client)->mac,
IPA_MAC_ADDR_SIZE);
+ /* replace src mac to bridge mac_addr if any */
+ if (IPACM_Iface::ipacmcfg->ipa_bridge_enable)
+ {
+ memcpy(&pHeaderDescriptor->hdr[0].hdr[data->attribs[i].offset+IPA_MAC_ADDR_SIZE],
+ IPACM_Iface::ipacmcfg->bridge_mac,
+ IPA_MAC_ADDR_SIZE);
+ IPACMDBG_H("device is in bridge mode \n");
+ }
+
}
else if(data->attribs[i].attrib_type == WLAN_HDR_ATTRIB_STA_ID)
{
@@ -1888,6 +1897,15 @@ int IPACM_Wlan::handle_wlan_client_init_ex(ipacm_event_data_wlan_ex *data)
memcpy(&pHeaderDescriptor->hdr[0].hdr[data->attribs[i].offset],
get_client_memptr(wlan_client, num_wifi_client)->mac,
IPA_MAC_ADDR_SIZE);
+
+ /* replace src mac to bridge mac_addr if any */
+ if (IPACM_Iface::ipacmcfg->ipa_bridge_enable)
+ {
+ memcpy(&pHeaderDescriptor->hdr[0].hdr[data->attribs[i].offset+IPA_MAC_ADDR_SIZE],
+ IPACM_Iface::ipacmcfg->bridge_mac,
+ IPA_MAC_ADDR_SIZE);
+ IPACMDBG_H("device is in bridge mode \n");
+ }
}
else if (data->attribs[i].attrib_type == WLAN_HDR_ATTRIB_STA_ID)
{