Merge "IPACM: support 8994 private subnet change"
diff --git a/ipacm/inc/IPACM_Config.h b/ipacm/inc/IPACM_Config.h
index 6587a77..dbc8789 100644
--- a/ipacm/inc/IPACM_Config.h
+++ b/ipacm/inc/IPACM_Config.h
@@ -42,7 +42,7 @@
#include "IPACM_Defs.h"
#include "IPACM_Xml.h"
-
+#include "IPACM_EvtDispatcher.h"
typedef struct
{
@@ -177,6 +177,82 @@
return false;
}
+#ifdef FEATURE_IPA_ANDROID
+ inline bool AddPrivateSubnet(uint32_t ip_addr, int ipa_if_index)
+ {
+ ipacm_cmd_q_data evt_data;
+ ipacm_event_data_fid *data_fid;
+ uint32_t subnet_mask = ~0;
+ for(int cnt=0; cnt<ipa_num_private_subnet; cnt++)
+ {
+ if(private_subnet_table[cnt].subnet_addr == ip_addr)
+ {
+ IPACMDBG("Already has private subnet_addr as: 0x%x in entry(%d) \n", ip_addr, cnt);
+ return true;
+ }
+ }
+
+ if(ipa_num_private_subnet < IPA_MAX_PRIVATE_SUBNET_ENTRIES)
+ {
+ IPACMDBG("Add IPACM private subnet_addr as: 0x%x in entry(%d) \n", ip_addr, ipa_num_private_subnet);
+ private_subnet_table[ipa_num_private_subnet].subnet_addr = ip_addr;
+ private_subnet_table[ipa_num_private_subnet].subnet_mask = (subnet_mask >> 8) << 8;
+ ipa_num_private_subnet++;
+
+ /* IPACM private subnet set changes */
+ data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
+ if(data_fid == NULL)
+ {
+ IPACMERR("unable to allocate memory for event data_fid\n");
+ return IPACM_FAILURE;
+ }
+ data_fid->if_index = ipa_if_index; // already ipa index, not fid index
+ evt_data.event = IPA_PRIVATE_SUBNET_CHANGE_EVENT;
+ evt_data.evt_data = data_fid;
+
+ /* Insert IPA_PRIVATE_SUBNET_CHANGE_EVENT to command queue */
+ IPACM_EvtDispatcher::PostEvt(&evt_data);
+ return true;
+ }
+ IPACMERR("IPACM private subnet_addr overflow, total entry(%d)\n", ipa_num_private_subnet);
+ return false;
+ }
+
+ inline bool DelPrivateSubnet(uint32_t ip_addr, int ipa_if_index)
+ {
+ ipacm_cmd_q_data evt_data;
+ ipacm_event_data_fid *data_fid;
+ for(int cnt=0; cnt<ipa_num_private_subnet; cnt++)
+ {
+ if(private_subnet_table[cnt].subnet_addr == ip_addr)
+ {
+ IPACMDBG("Found private subnet_addr as: 0x%x in entry(%d) \n", ip_addr, cnt);
+ for (; cnt < ipa_num_private_subnet - 1; cnt++)
+ {
+ private_subnet_table[cnt].subnet_addr = private_subnet_table[cnt+1].subnet_addr;
+ }
+ ipa_num_private_subnet = ipa_num_private_subnet - 1;
+
+ /* IPACM private subnet set changes */
+ data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
+ if(data_fid == NULL)
+ {
+ IPACMERR("unable to allocate memory for event data_fid\n");
+ return IPACM_FAILURE;
+ }
+ data_fid->if_index = ipa_if_index; // already ipa index, not fid index
+ evt_data.event = IPA_PRIVATE_SUBNET_CHANGE_EVENT;
+ evt_data.evt_data = data_fid;
+
+ /* Insert IPA_PRIVATE_SUBNET_CHANGE_EVENT to command queue */
+ IPACM_EvtDispatcher::PostEvt(&evt_data);
+ return true;
+ }
+ }
+ IPACMDBG("can't find private subnet_addr as: 0x%x \n", ip_addr);
+ return false;
+ }
+#endif /* defined(FEATURE_IPA_ANDROID)*/
private:
static IPACM_Config *pInstance;
diff --git a/ipacm/inc/IPACM_Defs.h b/ipacm/inc/IPACM_Defs.h
index 43c4589..3957d4c 100644
--- a/ipacm/inc/IPACM_Defs.h
+++ b/ipacm/inc/IPACM_Defs.h
@@ -155,6 +155,7 @@
IPA_WLAN_LINK_DOWN_EVENT, /* 37 ipacm_event_data_mac */
IPA_USB_LINK_UP_EVENT, /* 38 ipacm_event_data_fid */
IPA_PROCESS_CT_MESSAGE_V6, /* 39 ipacm_ct_evt_data */
+ IPA_PRIVATE_SUBNET_CHANGE_EVENT, /* 40 ipacm_event_data_fid */
IPACM_EVENT_MAX
} ipa_cm_event_id;
diff --git a/ipacm/inc/IPACM_Iface.h b/ipacm/inc/IPACM_Iface.h
index 0520dba..f661974 100644
--- a/ipacm/inc/IPACM_Iface.h
+++ b/ipacm/inc/IPACM_Iface.h
@@ -74,8 +74,8 @@
/* IPACM interface id */
int ipa_if_num;
- /* IPACM interface category */
- int ipa_if_cate;
+ /* IPACM interface category */
+ int ipa_if_cate;
/* IPACM interface name */
char dev_name[IF_NAME_LEN];
diff --git a/ipacm/inc/IPACM_Lan.h b/ipacm/inc/IPACM_Lan.h
index 45eb9ee..92475cb 100644
--- a/ipacm/inc/IPACM_Lan.h
+++ b/ipacm/inc/IPACM_Lan.h
@@ -112,7 +112,7 @@
uint32_t lan_wan_fl_rule_hdl[IPA_WAN_DEFAULT_FILTER_RULE_HANDLES];
/* store private-subnet filter rule handlers */
- uint32_t private_fl_rule_hdl[IPA_PRIV_SUBNET_FILTER_RULE_HANDLES];
+ uint32_t private_fl_rule_hdl[IPA_MAX_PRIVATE_SUBNET_ENTRIES];
/* LAN-iface's callback function */
void event_callback(ipa_cm_event_id event,
@@ -155,6 +155,10 @@
virtual int add_dummy_lan2lan_flt_rule(ipa_ip_type iptype);
+ virtual int add_dummy_private_subnet_flt_rule(ipa_ip_type iptype);
+
+ int handle_private_subnet_android(ipa_ip_type iptype);
+
int reset_to_dummy_flt_rule(ipa_ip_type iptype, uint32_t rule_hdl);
/*handle lan2lan client active*/
@@ -187,6 +191,8 @@
bool is_active;
+ uint32_t if_ipv4_subnet;
+
private:
/* dynamically allocate lan iface's unicast routing rule structure */
diff --git a/ipacm/inc/IPACM_Netlink.h b/ipacm/inc/IPACM_Netlink.h
index d379031..b0bdeb8 100644
--- a/ipacm/inc/IPACM_Netlink.h
+++ b/ipacm/inc/IPACM_Netlink.h
@@ -150,6 +150,10 @@
unsigned int param_mask;
unsigned char label_name[IF_NAME_LEN];
struct sockaddr_storage prefix_addr;
+ struct sockaddr_storage local_addr;
+ struct sockaddr_storage bcast_addr;
+ struct sockaddr_storage acast_addr;
+ struct sockaddr_storage mcast_addr;
} attr_info;
} ipa_nl_addr_info_t;
diff --git a/ipacm/inc/IPACM_Wlan.h b/ipacm/inc/IPACM_Wlan.h
index ce875e0..631713a 100644
--- a/ipacm/inc/IPACM_Wlan.h
+++ b/ipacm/inc/IPACM_Wlan.h
@@ -245,6 +245,8 @@
virtual int add_dummy_lan2lan_flt_rule(ipa_ip_type iptype);
+ virtual int add_dummy_private_subnet_flt_rule(ipa_ip_type iptype);
+
/*configure private subnet filter rules*/
virtual int handle_private_subnet(ipa_ip_type iptype);
diff --git a/ipacm/src/IPACM_IfaceManager.cpp b/ipacm/src/IPACM_IfaceManager.cpp
index 9c258a8..e0e115b 100644
--- a/ipacm/src/IPACM_IfaceManager.cpp
+++ b/ipacm/src/IPACM_IfaceManager.cpp
@@ -163,7 +163,8 @@
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6, lan);
IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, lan);
IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, lan);
- IPACM_EvtDispatcher::registr(IPA_CFG_CHANGE_EVENT, lan); // register for IPA_CFG_CHANGE event
+ 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
IPACMDBG("ipa_LAN (%s):ipa_index (%d) instance open/registr ok\n", lan->dev_name, lan->ipa_if_num);
registr(ipa_interface_index, lan);
/* solve the new_addr comes earlier issue */
@@ -207,6 +208,7 @@
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6, wl);
IPACM_EvtDispatcher::registr(IPA_WLAN_LINK_DOWN_EVENT, wl);
IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, wl);
+ IPACM_EvtDispatcher::registr(IPA_PRIVATE_SUBNET_CHANGE_EVENT, wl); // register for IPA_PRIVATE_SUBNET_CHANGE_EVENT event
IPACMDBG("ipa_WLAN (%s):ipa_index (%d) instance open/registr ok\n", wl->dev_name, wl->ipa_if_num);
registr(ipa_interface_index, wl);
/* solve the new_addr comes earlier issue */
diff --git a/ipacm/src/IPACM_Lan.cpp b/ipacm/src/IPACM_Lan.cpp
index 8e0d44d..5d48d87 100644
--- a/ipacm/src/IPACM_Lan.cpp
+++ b/ipacm/src/IPACM_Lan.cpp
@@ -53,7 +53,6 @@
IPACM_Lan::IPACM_Lan(int iface_index) : IPACM_Iface(iface_index)
{
-
num_eth_client = 0;
header_name_count = 0;
@@ -99,6 +98,8 @@
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));
is_mode_switch = false;
+ if_ipv4_subnet =0;
+ memset(private_fl_rule_hdl, 0, IPA_MAX_PRIVATE_SUBNET_ENTRIES * sizeof(uint32_t));
return;
}
@@ -153,6 +154,27 @@
}
break;
+ case IPA_PRIVATE_SUBNET_CHANGE_EVENT:
+ {
+ ipacm_event_data_fid *data = (ipacm_event_data_fid *)param;
+ /* internel event: data->if_index is ipa_if_index */
+ if (data->if_index == ipa_if_num)
+ {
+ IPACMDBG("Received IPA_PRIVATE_SUBNET_CHANGE_EVENT from itself posting, ignore\n");
+ return;
+ }
+ else
+ {
+ IPACMDBG("Received IPA_PRIVATE_SUBNET_CHANGE_EVENT from other LAN iface \n");
+#ifdef FEATURE_IPA_ANDROID
+ handle_private_subnet_android(IPA_IP_v4);
+#endif
+ IPACMDBG(" delete old private subnet rules, use new sets \n");
+ return;
+ }
+ }
+ break;
+
case IPA_LAN_DELETE_SELF:
{
ipacm_event_data_fid *data = (ipacm_event_data_fid *)param;
@@ -216,7 +238,12 @@
{
return;
}
+#ifdef FEATURE_IPA_ANDROID
+ add_dummy_private_subnet_flt_rule(data->iptype);
+ handle_private_subnet_android(data->iptype);
+#else
handle_private_subnet(data->iptype);
+#endif
if (IPACM_Wan::isWanUP())
{
@@ -433,6 +460,10 @@
+ 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
+
if(is_sta_mode == false)
{
if (num_wan_ul_fl_rule_v4 > MAX_WAN_UL_FILTER_RULES)
@@ -495,6 +526,21 @@
IPACMDBG("set route/filter rule ip-type: %d \n", data->iptype);
+/* Add private subnet*/
+#ifdef FEATURE_IPA_ANDROID
+if (data->iptype == IPA_IP_v4)
+{
+// IPACMDBG("Origin IPACM private subnet_addr as: 0x%x \n", data->ipv4_addr);
+ IPACMDBG("current IPACM private subnet_addr number(%d)\n", IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
+ if_ipv4_subnet = (data->ipv4_addr >> 8) << 8;
+ IPACMDBG(" Add IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
+ if(IPACM_Iface::ipacmcfg->AddPrivateSubnet(if_ipv4_subnet, ipa_if_num) == false)
+ {
+ IPACMERR(" can't Add IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
+ }
+}
+#endif /* defined(FEATURE_IPA_ANDROID)*/
+
if (data->iptype == IPA_IP_v4)
{
rt_rule = (struct ipa_ioc_add_rt_rule *)
@@ -1714,12 +1760,21 @@
goto fail;
}
+#ifdef FEATURE_IPA_ANDROID
+ if(m_filtering.DeleteFilteringHdls(private_fl_rule_hdl, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES) == false)
+ {
+ IPACMERR("Error deleting private subnet IPv4 flt rules.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+#else
if (m_filtering.DeleteFilteringHdls(private_fl_rule_hdl, IPA_IP_v4, IPACM_Iface::ipacmcfg->ipa_num_private_subnet) == false)
{
IPACMERR("Error Deleting RuleTable(1) to Filtering, aborting...\n");
res = IPACM_FAILURE;
goto fail;
}
+#endif
}
IPACMDBG("Finished delete default iface ipv4 filtering rules \n ");
@@ -1772,6 +1827,18 @@
/* posting ip to lan2lan module to delete RT/FILTER rules*/
post_lan2lan_client_disconnect_msg();
+/* Delete private subnet*/
+#ifdef FEATURE_IPA_ANDROID
+if (ip_type != IPA_IP_v6)
+{
+ IPACMDBG("current IPACM private subnet_addr number(%d)\n", IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
+ IPACMDBG(" Delete IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
+ if(IPACM_Iface::ipacmcfg->DelPrivateSubnet(if_ipv4_subnet, ipa_if_num) == false)
+ {
+ IPACMERR(" can't Delete IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
+ }
+}
+#endif /* defined(FEATURE_IPA_ANDROID)*/
fail:
/* Delete corresponding ipa_rm_resource_name of RX-endpoint after delete all IPV4V6 FT-rule */
if (rx_prop != NULL)
@@ -3197,3 +3264,162 @@
free(pFilteringTable);
return;
}
+
+int IPACM_Lan::add_dummy_private_subnet_flt_rule(ipa_ip_type iptype)
+{
+ if(rx_prop == NULL)
+ {
+ IPACMDBG("There is no rx_prop for iface %s, not able to add dummy private subnet 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_MAX_PRIVATE_SUBNET_ENTRIES * 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_MAX_PRIVATE_SUBNET_ENTRIES;
+
+ 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_MAX_PRIVATE_SUBNET_ENTRIES; i++)
+ {
+ memcpy(&(pFilteringTable->rules[i]), &flt_rule, sizeof(struct ipa_flt_rule_add));
+ }
+
+ if (false == m_filtering.AddFilteringRule(pFilteringTable))
+ {
+ IPACMERR("Error adding dummy private subnet v4 flt rule\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ else
+ {
+ flt_rule_count_v4 += IPA_MAX_PRIVATE_SUBNET_ENTRIES;
+ /* copy filter rule hdls */
+ for (int i = 0; i < IPA_MAX_PRIVATE_SUBNET_ENTRIES; i++)
+ {
+ if (pFilteringTable->rules[i].status == 0)
+ {
+ private_fl_rule_hdl[i] = pFilteringTable->rules[i].flt_rule_hdl;
+ IPACMDBG("Private subnet v4 flt rule %d hdl:0x%x\n", i, private_fl_rule_hdl[i]);
+ }
+ else
+ {
+ IPACMERR("Failed adding lan2lan v4 flt rule %d\n", i);
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ }
+ }
+ }
+fail:
+ free(pFilteringTable);
+ return res;
+}
+
+int IPACM_Lan::handle_private_subnet_android(ipa_ip_type iptype)
+{
+ int i, len, res = IPACM_SUCCESS, offset;
+ struct ipa_flt_rule_mdfy flt_rule;
+ struct ipa_ioc_mdfy_flt_rule* pFilteringTable;
+
+ if (rx_prop == NULL)
+ {
+ IPACMDBG("No rx properties registered for iface %s\n", dev_name);
+ return IPACM_SUCCESS;
+ }
+
+ if (iptype == IPA_IP_v4)
+ {
+ for(i=0; i<IPA_MAX_PRIVATE_SUBNET_ENTRIES; i++)
+ {
+ reset_to_dummy_flt_rule(IPA_IP_v4, private_fl_rule_hdl[i]);
+ }
+
+ 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;
+
+ /* Make LAN-traffic always go A5, use default IPA-RT table */
+ if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_default_v4))
+ {
+ IPACMERR("Failed to get routing table handle.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ 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_ROUTING;
+ flt_rule.rule.eq_attrib_type = 0;
+ flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_default_v4.hdl;
+ IPACMDBG("Private filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_default_v4.name);
+
+ 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 = private_fl_rule_hdl[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 private subnet filtering rules.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ }
+fail:
+ if(pFilteringTable != NULL)
+ {
+ free(pFilteringTable);
+ }
+ return res;
+}
diff --git a/ipacm/src/IPACM_Main.cpp b/ipacm/src/IPACM_Main.cpp
index d7347f4..54d049b 100644
--- a/ipacm/src/IPACM_Main.cpp
+++ b/ipacm/src/IPACM_Main.cpp
@@ -107,10 +107,11 @@
__stringify(IPA_LAN_CLIENT_POWER_RECOVER), /* 33 ipacm_event_lan_client*/
__stringify(IPA_LAN_TO_LAN_NEW_CONNECTION), /* 34 ipacm_event_connection */
__stringify(IPA_LAN_TO_LAN_DEL_CONNECTION), /* 35 ipacm_event_connection */
- __stringify(IPA_LAN_DELETE_SELF), /* 36 ipacm_event_data_fid */
- __stringify(IPA_WLAN_LINK_DOWN_EVENT), /* 37 ipacm_event_data_mac */
- __stringify(IPA_USB_LINK_UP_EVENT), /* 38 ipacm_event_data_fid */
- __stringify(IPA_PROCESS_CT_MESSAGE_V6), /* 39 ipacm_ct_evt_data */
+ __stringify(IPA_LAN_DELETE_SELF), /* 36 ipacm_event_data_fid */
+ __stringify(IPA_WLAN_LINK_DOWN_EVENT), /* 37 ipacm_event_data_mac */
+ __stringify(IPA_USB_LINK_UP_EVENT), /* 38 ipacm_event_data_fid */
+ __stringify(IPA_PROCESS_CT_MESSAGE_V6), /* 39 ipacm_ct_evt_data */
+ __stringify(IPA_PRIVATE_SUBNET_CHANGE_EVENT), /* 40 ipacm_event_data_fid */
};
#define IPA_DRIVER "/dev/ipa"
diff --git a/ipacm/src/IPACM_Netlink.cpp b/ipacm/src/IPACM_Netlink.cpp
index 012668e..114e6d6 100644
--- a/ipacm/src/IPACM_Netlink.cpp
+++ b/ipacm/src/IPACM_Netlink.cpp
@@ -452,7 +452,6 @@
IPACM_NL_COPY_ADDR( addr_info, prefix_addr );
addr_info->attr_info.param_mask |= IPA_NLA_PARAM_PREFIXADDR;
break;
-
default:
break;
diff --git a/ipacm/src/IPACM_Wlan.cpp b/ipacm/src/IPACM_Wlan.cpp
index 05f3674..2b68bc7 100644
--- a/ipacm/src/IPACM_Wlan.cpp
+++ b/ipacm/src/IPACM_Wlan.cpp
@@ -151,6 +151,27 @@
}
break;
+ case IPA_PRIVATE_SUBNET_CHANGE_EVENT:
+ {
+ ipacm_event_data_fid *data = (ipacm_event_data_fid *)param;
+ /* internel event: data->if_index is ipa_if_index */
+ if (data->if_index == ipa_if_num)
+ {
+ IPACMDBG("Received IPA_PRIVATE_SUBNET_CHANGE_EVENT from itself posting, ignore\n");
+ return;
+ }
+ else
+ {
+ IPACMDBG("Received IPA_PRIVATE_SUBNET_CHANGE_EVENT from other LAN iface \n");
+#ifdef FEATURE_IPA_ANDROID
+ handle_private_subnet_android(IPA_IP_v4);
+#endif
+ IPACMDBG(" delete old private subnet rules, use new sets \n");
+ return;
+ }
+ }
+ break;
+
case IPA_LAN_DELETE_SELF:
{
ipacm_event_data_fid *data = (ipacm_event_data_fid *)param;
@@ -220,7 +241,12 @@
{
return;
}
+#ifdef FEATURE_IPA_ANDROID
+ add_dummy_private_subnet_flt_rule(data->iptype);
+ handle_private_subnet_android(data->iptype);
+#else
handle_private_subnet(data->iptype);
+#endif
if (IPACM_Wan::isWanUP())
{
@@ -546,6 +572,10 @@
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 + MAX_OFFLOAD_PAIR;
#endif
+
+#ifdef FEATURE_IPA_ANDROID
+ offset = offset + wlan_ap_index * (IPA_MAX_PRIVATE_SUBNET_ENTRIES - IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
+#endif
len = sizeof(struct ipa_ioc_mdfy_flt_rule) + (IPV4_DEFAULT_FILTERTING_RULES * sizeof(struct ipa_flt_rule_mdfy));
pFilteringTable = (struct ipa_ioc_mdfy_flt_rule *)calloc(1, len);
if (!pFilteringTable)
@@ -740,6 +770,9 @@
+ NUM_TCP_CTL_FLT_RULE;
#endif
+#ifdef FEATURE_IPA_ANDROID
+ offset = offset + wlan_ap_index * (IPA_MAX_PRIVATE_SUBNET_ENTRIES - IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
+#endif
for (int i = 0; i < MAX_OFFLOAD_PAIR; i++)
{
lan2lan_flt_rule_hdl_v4[i].rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v4[offset+i];
@@ -958,6 +991,10 @@
#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
}
else
{
@@ -1804,6 +1841,17 @@
IPACMDBG("Delete private v4 filter rules\n");
/* delete private-ipv4 filter rules */
+#ifdef FEATURE_IPA_ANDROID
+ for(i=0; i<IPA_MAX_PRIVATE_SUBNET_ENTRIES; i++)
+ {
+ 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;
+ }
+ }
+#else
for(i=0; i<IPACM_Iface::ipacmcfg->ipa_num_private_subnet; i++)
{
if(reset_to_dummy_flt_rule(IPA_IP_v4, private_fl_rule_hdl[i]) == IPACM_FAILURE)
@@ -1813,6 +1861,7 @@
goto fail;
}
}
+#endif
}
/* Delete v6 filtering rules */
@@ -1948,6 +1997,19 @@
/* free the wlan clients cache */
IPACMDBG("Free wlan clients cache\n");
+ /* Delete private subnet*/
+#ifdef FEATURE_IPA_ANDROID
+ if (ip_type != IPA_IP_v6)
+ {
+ IPACMDBG("current IPACM private subnet_addr number(%d)\n", IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
+ IPACMDBG(" Delete IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
+ if(IPACM_Iface::ipacmcfg->DelPrivateSubnet(if_ipv4_subnet, ipa_if_num) == false)
+ {
+ IPACMERR(" can't Delete IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
+ }
+ }
+#endif /* defined(FEATURE_IPA_ANDROID)*/
+
fail:
/* Delete corresponding ipa_rm_resource_name of RX-endpoint after delete all IPV4V6 FT-rule */
if (rx_prop != NULL)
@@ -2352,6 +2414,11 @@
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
+
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)
{
@@ -2533,6 +2600,11 @@
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
+
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");
@@ -2572,6 +2644,9 @@
return;
}
offset = wlan_ap_index * (IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
+#ifdef FEATURE_IPA_ANDROID
+ offset = offset + wlan_ap_index * (IPA_MAX_PRIVATE_SUBNET_ENTRIES - IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
+#endif
}
else
{
@@ -2686,3 +2761,39 @@
return;
}
+int IPACM_Wlan::add_dummy_private_subnet_flt_rule(ipa_ip_type iptype)
+{
+ if(rx_prop == NULL)
+ {
+ IPACMDBG("There is no rx_prop for iface %s, not able to add dummy lan2lan filtering rule.\n", dev_name);
+ return IPACM_FAILURE;
+ }
+
+ int offset;
+ 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;
+ }
+
+#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;
+#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 + MAX_OFFLOAD_PAIR + NUM_TCP_CTL_FLT_RULE;
+#endif
+
+#ifdef FEATURE_IPA_ANDROID
+ offset = offset + wlan_ap_index * (IPA_MAX_PRIVATE_SUBNET_ENTRIES - IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
+#endif
+ for (int i = 0; i < IPA_MAX_PRIVATE_SUBNET_ENTRIES; i++)
+ {
+ private_fl_rule_hdl[i] = IPACM_Wlan::dummy_flt_rule_hdl_v4[offset+i];
+ IPACMDBG("Private subnet v4 flt rule %d hdl:0x%x\n", i, private_fl_rule_hdl[i]);
+ }
+ }
+ return IPACM_SUCCESS;
+}
\ No newline at end of file