Merge "IPACM: eMBMS traffic take offload path on ODU only"
diff --git a/ipacm/inc/IPACM_Config.h b/ipacm/inc/IPACM_Config.h
index 69080ad..5a79849 100644
--- a/ipacm/inc/IPACM_Config.h
+++ b/ipacm/inc/IPACM_Config.h
@@ -123,6 +123,10 @@
/* Store SW-enable or not */
bool ipa_sw_rt_enable;
+ /* 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];
+
/* IPACM routing table name for v4/v6 */
struct ipa_ioc_get_rt_tbl rt_tbl_lan_v4, rt_tbl_wan_v4, rt_tbl_default_v4, rt_tbl_v6, rt_tbl_wan_v6;
struct ipa_ioc_get_rt_tbl rt_tbl_wan_dl;
@@ -136,6 +140,63 @@
/* To return the instance */
static IPACM_Config* GetInstance();
+ inline void increaseFltRuleCount(int index, ipa_ip_type iptype, int increment)
+ {
+ if((index >= IPA_CLIENT_CONS - IPA_CLIENT_PROD) || (index < 0))
+ {
+ IPACMERR("Index is out of range: %d.\n", index);
+ return;
+ }
+ if(iptype == IPA_IP_v4)
+ {
+ flt_rule_count_v4[index] += increment;
+ IPACMDBG_H("Now num of v4 flt rules on client %d is %d.\n", index, flt_rule_count_v4[index]);
+ }
+ else
+ {
+ flt_rule_count_v6[index] += increment;
+ IPACMDBG_H("Now num of v6 flt rules on client %d is %d.\n", index, flt_rule_count_v6[index]);
+ }
+ return;
+ }
+
+ inline void decreaseFltRuleCount(int index, ipa_ip_type iptype, int decrement)
+ {
+ if((index >= IPA_CLIENT_CONS - IPA_CLIENT_PROD) || (index < 0))
+ {
+ IPACMERR("Index is out of range: %d.\n", index);
+ return;
+ }
+ if(iptype == IPA_IP_v4)
+ {
+ flt_rule_count_v4[index] -= decrement;
+ IPACMDBG_H("Now num of v4 flt rules on client %d is %d.\n", index, flt_rule_count_v4[index]);
+ }
+ else
+ {
+ flt_rule_count_v6[index] -= decrement;
+ IPACMDBG_H("Now num of v6 flt rules on client %d is %d.\n", index, flt_rule_count_v6[index]);
+ }
+ return;
+ }
+
+ inline int getFltRuleCount(int index, ipa_ip_type iptype)
+ {
+ if((index >= IPA_CLIENT_CONS - IPA_CLIENT_PROD) || (index < 0))
+ {
+ IPACMERR("Index is out of range: %d.\n", index);
+ return -1;
+ }
+ if(iptype == IPA_IP_v4)
+ {
+ return flt_rule_count_v4[index];
+ }
+ else
+ {
+ return flt_rule_count_v6[index];
+ }
+ }
+
inline int GetAlgPortCnt()
{
return ipa_num_alg_ports;
diff --git a/ipacm/inc/IPACM_Conntrack_NATApp.h b/ipacm/inc/IPACM_Conntrack_NATApp.h
index 7c97225..1fb12bf 100644
--- a/ipacm/inc/IPACM_Conntrack_NATApp.h
+++ b/ipacm/inc/IPACM_Conntrack_NATApp.h
@@ -52,6 +52,7 @@
uint32_t target_ip;
uint16_t target_port;
+ uint16_t public_ip;
uint16_t public_port;
u_int8_t protocol;
@@ -74,6 +75,7 @@
nat_table_entry *cache;
nat_table_entry temp[MAX_TEMP_ENTRIES];
uint32_t pub_ip_addr;
+ uint32_t pub_ip_addr_pre;
uint32_t nat_table_hdl;
int curCnt, max_entries;
@@ -118,6 +120,7 @@
void UpdateTcpUdpTo(uint32_t, int proto);
void AddTempEntry(const nat_table_entry *);
+ void CacheEntry(const nat_table_entry *);
void DeleteTempEntry(const nat_table_entry *);
void FlushTempEntries(uint32_t, bool);
};
diff --git a/ipacm/inc/IPACM_Defs.h b/ipacm/inc/IPACM_Defs.h
index 45ea6c0..37f3ff4 100644
--- a/ipacm/inc/IPACM_Defs.h
+++ b/ipacm/inc/IPACM_Defs.h
@@ -101,7 +101,7 @@
#define IPA_LAN_TO_LAN_WLAN_HDR_NAME_V4 "Lan2Lan_Wlan_v4"
#define IPA_LAN_TO_LAN_WLAN_HDR_NAME_V6 "Lan2Lan_Wlan_v6"
#define IPA_LAN_TO_LAN_MAX_WLAN_CLIENT 32
-#define IPA_LAN_TO_LAN_MAX_USB_CLIENT 1
+#define IPA_LAN_TO_LAN_MAX_USB_CLIENT 15
#define TCP_FIN_SHIFT 16
#define TCP_SYN_SHIFT 17
#define TCP_RST_SHIFT 18
@@ -179,6 +179,7 @@
IPA_ETH_BRIDGE_HDR_PROC_CTX_UNSET_EVENT, /* 49 ipacm_event_data_fid */
IPA_WLAN_SWITCH_TO_SCC, /* 50 No Data */
IPA_WLAN_SWITCH_TO_MCC, /* 51 No Data */
+ IPA_CRADLE_WAN_MODE_SWITCH, /* 52 ipacm_event_cradle_wan_mode */
IPACM_EVENT_MAX
} ipa_cm_event_id;
@@ -200,6 +201,12 @@
UNKNOWN_IF
} ipacm_iface_type;
+typedef enum
+{
+ ROUTER = 0,
+ BRIDGE
+} ipacm_iface_mode;
+
typedef struct
{
struct nf_conntrack *ct;
@@ -210,6 +217,7 @@
{
char iface_name[IPA_IFACE_NAME_LEN];
ipacm_iface_type if_cat;
+ ipacm_iface_mode if_mode;
int netlink_interface_index;
} ipa_ifi_dev_name_t;
@@ -233,6 +241,11 @@
typedef struct
{
+ ipacm_iface_mode cradle_wan_mode;
+} ipacm_event_cradle_wan_mode;
+
+typedef struct
+{
enum ipa_ip_type iptype;
uint32_t ipv4_addr;
uint32_t ipv6_addr[4];
@@ -265,6 +278,7 @@
{
enum ipa_ip_type iptype;
int if_index;
+ uint32_t ipv4_addr_gw;
uint32_t ipv4_addr;
uint32_t ipv4_addr_mask;
uint32_t ipv6_addr[4];
diff --git a/ipacm/inc/IPACM_Iface.h b/ipacm/inc/IPACM_Iface.h
index f661974..278ed24 100644
--- a/ipacm/inc/IPACM_Iface.h
+++ b/ipacm/inc/IPACM_Iface.h
@@ -144,11 +144,6 @@
/* software routing disable */
virtual int handle_software_routing_disable(void);
- /* used to get filtering rule index in table */
- int flt_rule_count_v4;
-
- int flt_rule_count_v6;
-
private:
static const char *DEVICE_NAME;
diff --git a/ipacm/inc/IPACM_Lan.h b/ipacm/inc/IPACM_Lan.h
index 505f426..68669c0 100644
--- a/ipacm/inc/IPACM_Lan.h
+++ b/ipacm/inc/IPACM_Lan.h
@@ -53,7 +53,7 @@
#define IPA_WAN_DEFAULT_FILTER_RULE_HANDLES 1
#define IPA_PRIV_SUBNET_FILTER_RULE_HANDLES 3
#define IPA_NUM_ODU_ROUTE_RULES 2
-#define MAX_WAN_UL_FILTER_RULES 20
+#define MAX_WAN_UL_FILTER_RULES MAX_NUM_EXT_PROPS
#define NUM_IPV6_PREFIX_FLT_RULE 1
#define NUM_IPV6_ICMP_FLT_RULE 1
@@ -185,6 +185,7 @@
int del_lan2lan_hdr(ipa_ip_type iptype, uint32_t hdr_hdl);
+ int handle_cradle_wan_mode_switch(bool is_wan_bridge_mode);
static ipa_hdr_l2_type usb_hdr_type;
@@ -303,6 +304,10 @@
uint32_t if_ipv4_subnet;
+ /* expected modem UL rules starting index */
+ int exp_index_v4;
+ int exp_index_v6;
+
private:
/* dynamically allocate lan iface's unicast routing rule structure */
diff --git a/ipacm/inc/IPACM_Log.h b/ipacm/inc/IPACM_Log.h
index f2ed773..131aab8 100644
--- a/ipacm/inc/IPACM_Log.h
+++ b/ipacm/inc/IPACM_Log.h
@@ -65,12 +65,18 @@
void ipacm_log_send( void * user_data);
static char buffer_send[MAX_BUF_LEN];
+static char dmesg_cmd[MAX_BUF_LEN];
#define PERROR(fmt) memset(buffer_send, 0, MAX_BUF_LEN);\
snprintf(buffer_send,MAX_BUF_LEN,"%s:%d %s()", __FILE__, __LINE__, __FUNCTION__);\
ipacm_log_send (buffer_send); \
perror(fmt);
+#define IPACMDBG_DMESG(fmt, ...) memset(buffer_send, 0, MAX_BUF_LEN);\
+ snprintf(buffer_send,MAX_BUF_LEN,"%s:%d %s: " fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__);\
+ memset(dmesg_cmd, 0, MAX_BUF_LEN);\
+ snprintf(dmesg_cmd, MAX_BUF_LEN, "echo %s > /dev/kmsg", buffer_send);\
+ system(dmesg_cmd);
#define IPACMERR(fmt, ...) memset(buffer_send, 0, MAX_BUF_LEN);\
snprintf(buffer_send,MAX_BUF_LEN,"ERR: %s:%d %s() " fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__);\
ipacm_log_send (buffer_send);\
diff --git a/ipacm/inc/IPACM_Wan.h b/ipacm/inc/IPACM_Wan.h
index 07036f0..5160ac3 100644
--- a/ipacm/inc/IPACM_Wan.h
+++ b/ipacm/inc/IPACM_Wan.h
@@ -116,6 +116,7 @@
static uint32_t backhaul_ipv6_prefix[2];
static bool embms_is_on;
+ static bool cradle_backhaul_is_wan_bridge;
private:
@@ -133,7 +134,9 @@
uint32_t ODU_fl_hdl[IPA_NUM_DEFAULT_WAN_FILTER_RULES];
int num_firewall_v4,num_firewall_v6;
uint32_t wan_v4_addr;
+ uint32_t wan_v4_addr_gw;
bool wan_v4_addr_set;
+ bool wan_v4_addr_gw_set;
bool active_v4;
bool active_v6;
bool header_set_v4;
@@ -203,6 +206,39 @@
return IPACM_INVALID_INDEX;
}
+ inline int get_wan_client_index_ipv4(uint32_t ipv4_addr)
+ {
+ int cnt;
+ int num_wan_client_tmp = num_wan_client;
+
+ IPACMDBG_H("Passed IPv4 %x\n", ipv4_addr);
+
+ for(cnt = 0; cnt < num_wan_client_tmp; cnt++)
+ {
+ if (get_client_memptr(wan_client, cnt)->ipv4_set)
+ {
+ IPACMDBG_H("stored IPv4 %x\n", get_client_memptr(wan_client, cnt)->v4_addr);
+
+ if(ipv4_addr == get_client_memptr(wan_client, cnt)->v4_addr)
+ {
+ IPACMDBG_H("Matched client index: %d\n", cnt);
+ IPACMDBG_H("The MAC is %02x:%02x:%02x:%02x:%02x:%02x\n",
+ get_client_memptr(wan_client, cnt)->mac[0],
+ get_client_memptr(wan_client, cnt)->mac[1],
+ get_client_memptr(wan_client, cnt)->mac[2],
+ get_client_memptr(wan_client, cnt)->mac[3],
+ get_client_memptr(wan_client, cnt)->mac[4],
+ get_client_memptr(wan_client, cnt)->mac[5]);
+ IPACMDBG_H("header set ipv4(%d) ipv6(%d)\n",
+ get_client_memptr(wan_client, cnt)->ipv4_header_set,
+ get_client_memptr(wan_client, cnt)->ipv6_header_set);
+ return cnt;
+ }
+ }
+ }
+ return IPACM_INVALID_INDEX;
+ }
+
inline int delete_wan_rtrules(int clt_indx, ipa_ip_type iptype)
{
uint32_t tx_index;
@@ -278,8 +314,8 @@
/* wan default route/filter rule configuration */
int handle_route_add_evt(ipa_ip_type iptype);
- /* construct complete ethernet header */
- int handle_header_add_evt(uint8_t *mac_addr);
+ /* construct complete STA ethernet header */
+ int handle_sta_header_add_evt();
int config_dft_firewall_rules(ipa_ip_type iptype);
diff --git a/ipacm/inc/IPACM_Wlan.h b/ipacm/inc/IPACM_Wlan.h
index 37584e2..fb5555a 100644
--- a/ipacm/inc/IPACM_Wlan.h
+++ b/ipacm/inc/IPACM_Wlan.h
@@ -322,6 +322,11 @@
int handle_wlan_client_reset_rt(ipa_ip_type iptype);
void handle_SCC_MCC_switch(ipa_ip_type);
+
+ void eth_bridge_handle_wlan_SCC_MCC_switch(ipa_ip_type iptype);
+
+ int eth_bridge_modify_wlan_rt_rule(uint8_t* mac, eth_bridge_src_iface src_iface, ipa_ip_type iptyp);
+
};
diff --git a/ipacm/inc/IPACM_Xml.h b/ipacm/inc/IPACM_Xml.h
index 2b8d5d9..53cabad 100644
--- a/ipacm/inc/IPACM_Xml.h
+++ b/ipacm/inc/IPACM_Xml.h
@@ -85,6 +85,7 @@
#define IFACE_TAG "Iface"
#define NAME_TAG "Name"
#define CATEGORY_TAG "Category"
+#define MODE_TAG "Mode"
#define IPACMPRIVATESUBNETCFG_TAG "IPACMPrivateSubnet"
#define SUBNET_TAG "Subnet"
#define SUBNETADDRESS_TAG "SubnetAddress"
@@ -97,6 +98,8 @@
#define ODUIF_TAG "ODU"
#define EMBMSIF_TAG "EMBMS"
#define ETHIF_TAG "ETH"
+#define IFACE_ROUTER_MODE_TAG "ROUTER"
+#define IFACE_BRIDGE_MODE_TAG "BRIDGE"
#define IPACMALG_TAG "IPACMALG"
#define ALG_TAG "ALG"
#define Protocol_TAG "Protocol"
diff --git a/ipacm/src/Android.mk b/ipacm/src/Android.mk
index d80be81..ceae2b8 100644
--- a/ipacm/src/Android.mk
+++ b/ipacm/src/Android.mk
@@ -28,10 +28,10 @@
LOCAL_CFLAGS += -DFEATURE_IPA_ANDROID
LOCAL_CFLAGS += -DDEBUG
-ifeq ($(TARGET_ARCH),arm)
-LOCAL_CFLAGS += -include bionic/libc/kernel/arch-arm/asm/posix_types.h
-LOCAL_CFLAGS += -include bionic/libc/kernel/arch-arm/asm/byteorder.h
-endif
+filetoadd = bionic/libc/kernel/arch-arm/asm/posix_types.h
+LOCAL_CFLAGS += $(shell if [ -a $(filetoadd) ] ; then echo -include $(filetoadd) ; fi ;)
+filetoadd = bionic/libc/kernel/arch-arm/asm/byteorder.h
+LOCAL_CFLAGS += $(shell if [ -a $(filetoadd) ] ; then echo -include $(filetoadd) ; fi ;)
LOCAL_SRC_FILES := IPACM_Main.cpp \
IPACM_EvtDispatcher.cpp \
@@ -54,7 +54,7 @@
IPACM_Log.cpp
LOCAL_MODULE := ipacm
-LOCAL_MODULE_TAGS := debug
+LOCAL_MODULE_TAGS := optional
LOCAL_SHARED_LIBRARIES := libipanat
LOCAL_SHARED_LIBRARIES += libxml2
diff --git a/ipacm/src/IPACM_Config.cpp b/ipacm/src/IPACM_Config.cpp
index efc06fb..7ed3ade 100644
--- a/ipacm/src/IPACM_Config.cpp
+++ b/ipacm/src/IPACM_Config.cpp
@@ -85,6 +85,9 @@
qmap_id = ~0;
+ 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));
+
IPACMDBG_H(" create IPACM_Config constructor\n");
return;
}
@@ -145,7 +148,9 @@
{
strncpy(iface_table[i].iface_name, cfg->iface_config.iface_entries[i].iface_name, sizeof(iface_table[i].iface_name));
iface_table[i].if_cat = cfg->iface_config.iface_entries[i].if_cat;
- IPACMDBG_H("IPACM_Config::iface_table[%d] = %s, cat=%d\n", i, iface_table[i].iface_name, iface_table[i].if_cat);
+ iface_table[i].if_mode = cfg->iface_config.iface_entries[i].if_mode;
+ IPACMDBG_H("IPACM_Config::iface_table[%d] = %s, cat=%d, mode=%d\n", i, iface_table[i].iface_name,
+ iface_table[i].if_cat, iface_table[i].if_mode);
/* copy bridge interface name to ipacmcfg */
if( iface_table[i].if_cat == VIRTUAL_IF)
{
diff --git a/ipacm/src/IPACM_ConntrackClient.cpp b/ipacm/src/IPACM_ConntrackClient.cpp
index d8fe726..9de5911 100644
--- a/ipacm/src/IPACM_ConntrackClient.cpp
+++ b/ipacm/src/IPACM_ConntrackClient.cpp
@@ -113,19 +113,6 @@
goto IGNORE;
}
- if(!CtList->isWanUp())
- {
-#ifdef IPACM_DEBUG
- IPACMDBG("Wan is not up, ignoring below connections\n");
- char buf[1024];
- nfct_snprintf(buf, sizeof(buf), ct,
- type, NFCT_O_PLAIN, NFCT_OF_TIME);
- IPACMDBG("%s\n", buf);
- IPACMDBG("\n");
- ParseCTMessage(ct);
-#endif
- goto IGNORE;
- }
#endif
ct_data = (ipacm_ct_evt_data *)malloc(sizeof(ipacm_ct_evt_data));
diff --git a/ipacm/src/IPACM_ConntrackListener.cpp b/ipacm/src/IPACM_ConntrackListener.cpp
index e00f921..9e66a00 100644
--- a/ipacm/src/IPACM_ConntrackListener.cpp
+++ b/ipacm/src/IPACM_ConntrackListener.cpp
@@ -213,6 +213,7 @@
if(nat_iface_ipv4_addr[j] == 0)
{
nat_iface_ipv4_addr[j] = data->ipv4_addr;
+ nat_inst->ResetPwrSaveIf(data->ipv4_addr);
nat_inst->FlushTempEntries(data->ipv4_addr, true);
break;
}
@@ -702,11 +703,13 @@
{
IPACMDBG("orig src ip:0x%x equal to wan ip\n",orig_src_ip);
status = IPS_SRC_NAT;
+ rule.public_ip = wan_ipaddr;
}
else if(orig_dst_ip == wan_ipaddr)
{
IPACMDBG("orig Dst IP:0x%x equal to wan ip\n",orig_dst_ip);
status = IPS_DST_NAT;
+ rule.public_ip = wan_ipaddr;
}
else
{
@@ -933,7 +936,12 @@
if(TCP_CONNTRACK_ESTABLISHED == tcp_state)
{
IPACMDBG("TCP state TCP_CONNTRACK_ESTABLISHED(%d)\n", tcp_state);
- if(isTempEntry)
+ if(!CtList->isWanUp())
+ {
+ IPACMDBG("Wan is not up, cache connections\n");
+ nat_inst->CacheEntry(&rule);
+ }
+ else if(isTempEntry)
{
nat_inst->AddTempEntry(&rule);
}
@@ -973,7 +981,12 @@
if(NFCT_T_NEW == type)
{
IPACMDBG("New UDP connection at time %ld\n", time(NULL));
- if(isTempEntry)
+ if(!CtList->isWanUp())
+ {
+ IPACMDBG("Wan is not up, cache connections\n");
+ nat_inst->CacheEntry(&rule);
+ }
+ else if(isTempEntry)
{
nat_inst->AddTempEntry(&rule);
}
diff --git a/ipacm/src/IPACM_Conntrack_NATApp.cpp b/ipacm/src/IPACM_Conntrack_NATApp.cpp
index c4a7e52..0915fda 100644
--- a/ipacm/src/IPACM_Conntrack_NATApp.cpp
+++ b/ipacm/src/IPACM_Conntrack_NATApp.cpp
@@ -129,8 +129,19 @@
int NatApp::AddTable(uint32_t pub_ip)
{
int ret;
+ int cnt = 0;
+ ipa_nat_ipv4_rule nat_rule;
IPACMDBG("%s() %d\n", __FUNCTION__, __LINE__);
+ /* Not reset the cache wait it timeout by destroy event */
+#if 0
+ if (pub_ip != pub_ip_addr_pre)
+ {
+ IPACMDBG("Reset the cache because NAT-ipv4 different\n");
+ memset(cache, 0, sizeof(nat_table_entry) * max_entries);
+ curCnt = 0;
+ }
+#endif
ret = ipa_nat_add_ipv4_tbl(pub_ip, max_entries, &nat_table_hdl);
if(ret)
{
@@ -138,17 +149,56 @@
return ret;
}
+ /* Add back the cashed NAT-entry */
+ if (pub_ip == pub_ip_addr_pre)
+ {
+ IPACMDBG("Restore the cache to ipa NAT-table\n");
+ for(cnt = 0; cnt < max_entries; cnt++)
+ {
+ if(cache[cnt].private_ip !=0)
+ {
+ memset(&nat_rule, 0 , sizeof(nat_rule));
+ nat_rule.private_ip = cache[cnt].private_ip;
+ nat_rule.target_ip = cache[cnt].target_ip;
+ nat_rule.target_port = cache[cnt].target_port;
+ nat_rule.private_port = cache[cnt].private_port;
+ nat_rule.public_port = cache[cnt].public_port;
+ nat_rule.protocol = cache[cnt].protocol;
+
+ if(ipa_nat_add_ipv4_rule(nat_table_hdl, &nat_rule, &cache[cnt].rule_hdl) < 0)
+ {
+ IPACMERR("unable to add the rule delete from cache\n");
+ memset(&cache[cnt], 0, sizeof(cache[cnt]));
+ curCnt--;
+ continue;
+ }
+ cache[cnt].enabled = true;
+
+ IPACMDBG("On wan-iface reset added below rule successfully\n");
+ iptodot("Private IP", nat_rule.private_ip);
+ iptodot("Target IP", nat_rule.target_ip);
+ IPACMDBG("Private Port:%d \t Target Port: %d\t", nat_rule.private_port, nat_rule.target_port);
+ IPACMDBG("Public Port:%d\n", nat_rule.public_port);
+ IPACMDBG("protocol: %d\n", nat_rule.protocol);
+ }
+ }
+ }
+
pub_ip_addr = pub_ip;
return 0;
}
void NatApp::Reset()
{
- memset(cache, 0, sizeof(nat_table_entry) * max_entries);
+ int cnt = 0;
nat_table_hdl = 0;
pub_ip_addr = 0;
- curCnt = 0;
+ /* NAT tbl deleted, reset enabled bit */
+ for(cnt = 0; cnt < max_entries; cnt++)
+ {
+ cache[cnt].enabled ==false;
+ }
}
int NatApp::DeleteTable(uint32_t pub_ip)
@@ -172,6 +222,7 @@
return ret;
}
+ pub_ip_addr_pre = pub_ip_addr;
Reset();
return 0;
}
@@ -208,9 +259,7 @@
int cnt = 0;
IPACMDBG("%s() %d\n", __FUNCTION__, __LINE__);
- CHK_TBL_HDL();
-
- IPACMDBG("Received below nat entry for deletion\n");
+ IPACMDBG("Received below nat entry for deletion\n");
iptodot("Private IP", rule->private_ip);
iptodot("Target IP", rule->target_ip);
IPACMDBG("Private Port: %d\t Target Port: %d\t", rule->private_port, rule->target_port);
@@ -229,8 +278,7 @@
{
if(ipa_nat_del_ipv4_rule(nat_table_hdl, cache[cnt].rule_hdl) < 0)
{
- IPACMERR("%s() %d\n", __FUNCTION__, __LINE__);
- return -1;
+ IPACMERR("%s() %d deletion failed\n", __FUNCTION__, __LINE__);
}
IPACMDBG("Deleted Nat entry(%d) Successfully\n", cnt);
@@ -525,7 +573,6 @@
}
}
- CHK_TBL_HDL();
for(cnt = 0; cnt < IPA_MAX_NUM_WIFI_CLIENTS; cnt++)
{
@@ -579,6 +626,8 @@
for(cnt = 0; cnt < max_entries; cnt++)
{
+ IPACMDBG("cache (%d): enable %d, ip 0x%x\n", cnt, cache[cnt].enabled, cache[cnt].private_ip);
+
if(cache[cnt].private_ip == client_lan_ip &&
cache[cnt].enabled == false)
{
@@ -704,11 +753,14 @@
{
if(isAdd)
{
- ret = AddEntry(&temp[cnt]);
- if(ret)
+ if(temp[cnt].public_ip == pub_ip_addr)
{
- IPACMERR("unable to add temp entry: %d\n", ret);
- continue;
+ ret = AddEntry(&temp[cnt]);
+ if(ret)
+ {
+ IPACMERR("unable to add temp entry: %d\n", ret);
+ continue;
+ }
}
}
memset(&temp[cnt], 0, sizeof(nat_table_entry));
@@ -729,7 +781,6 @@
return -1;
}
- CHK_TBL_HDL();
for(cnt = 0; cnt < IPA_MAX_NUM_WIFI_CLIENTS; cnt++)
{
@@ -741,27 +792,28 @@
}
}
- for(cnt = 0; cnt < max_entries; cnt++)
+ for(cnt = 0; cnt < max_entries; cnt++)
+ {
+ if(cache[cnt].private_ip == ip_addr)
{
- if(cache[cnt].private_ip == ip_addr)
- {
-
- if(cache[cnt].enabled == true)
- {
+ if(cache[cnt].enabled == true)
+ {
if(ipa_nat_del_ipv4_rule(nat_table_hdl, cache[cnt].rule_hdl) < 0)
{
IPACMERR("unable to delete the rule\n");
continue;
}
- }
-
- memset(&cache[cnt], 0, sizeof(cache[cnt]));
- curCnt--;
- }
+ else
+ {
+ IPACMDBG("won't delete the rule\n");
+ cache[cnt].enabled = false;
+ }
+ }
+ IPACMDBG("won't delete the rule for entry %d, enabled %d\n",cnt, cache[cnt].enabled);
}
-
+ }
IPACMDBG("Deleted %d entries\n", (tmp - curCnt));
- return 0;
+ return 0;
}
int NatApp::DelEntriesOnSTAClntDiscon(uint32_t ip_addr)
@@ -775,7 +827,6 @@
return -1;
}
- CHK_TBL_HDL();
for(cnt = 0; cnt < max_entries; cnt++)
{
@@ -798,3 +849,61 @@
IPACMDBG("Deleted %d entries\n", (tmp - curCnt));
return 0;
}
+
+void NatApp::CacheEntry(const nat_table_entry *rule)
+{
+ int cnt;
+ if(rule->private_ip == 0 ||
+ rule->target_ip == 0 ||
+ rule->private_port == 0 ||
+ rule->target_port == 0 ||
+ rule->protocol == 0)
+ {
+ IPACMERR("Invalid Connection, ignoring it\n");
+ return;
+ }
+
+ if(!ChkForDup(rule))
+ {
+ for(; cnt < max_entries; cnt++)
+ {
+ if(cache[cnt].private_ip == 0 &&
+ cache[cnt].target_ip == 0 &&
+ cache[cnt].private_port == 0 &&
+ cache[cnt].target_port == 0 &&
+ cache[cnt].protocol == 0)
+ {
+ break;
+ }
+ }
+
+ if(max_entries == cnt)
+ {
+ IPACMERR("Error: Unable to add, reached maximum rules\n");
+ return;
+ }
+ else
+ {
+ cache[cnt].enabled = false;
+ cache[cnt].rule_hdl = 0;
+ cache[cnt].private_ip = rule->private_ip;
+ cache[cnt].target_ip = rule->target_ip;
+ cache[cnt].target_port = rule->target_port;
+ cache[cnt].private_port = rule->private_port;
+ cache[cnt].protocol = rule->protocol;
+ cache[cnt].timestamp = 0;
+ cache[cnt].public_port = rule->public_port;
+ cache[cnt].dst_nat = rule->dst_nat;
+ curCnt++;
+ }
+
+ }
+ else
+ {
+ IPACMERR("Duplicate rule. Ignore it\n");
+ return;
+ }
+
+ IPACMDBG("Cached rule(%d) successfully\n", cnt);
+ return;
+}
diff --git a/ipacm/src/IPACM_Iface.cpp b/ipacm/src/IPACM_Iface.cpp
index 729acf2..0606ab4 100644
--- a/ipacm/src/IPACM_Iface.cpp
+++ b/ipacm/src/IPACM_Iface.cpp
@@ -82,8 +82,6 @@
memset(software_routing_fl_rule_hdl, 0, sizeof(software_routing_fl_rule_hdl));
memset(ipv6_addr, 0, sizeof(ipv6_addr));
- flt_rule_count_v4 = 0;
- flt_rule_count_v6 = 0;
query_iface_property();
IPACMDBG_H(" create iface-index(%d) constructor\n", ipa_if_num);
return;
@@ -159,6 +157,7 @@
goto fail;
}
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1);
IPACMDBG("soft-routing flt rule hdl0=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl);
/* copy filter hdls */
software_routing_fl_rule_hdl[0] = m_pFilteringTable->rules[0].flt_rule_hdl;
@@ -179,6 +178,7 @@
goto fail;
}
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
IPACMDBG("soft-routing flt rule hdl0=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl);
/* copy filter hdls */
software_routing_fl_rule_hdl[1] = m_pFilteringTable->rules[0].flt_rule_hdl;
@@ -209,6 +209,7 @@
goto fail;
}
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, ip_type, 1);
IPACMDBG("soft-routing flt rule hdl0=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl);
/* copy filter hdls */
if (ip_type == IPA_IP_v4)
@@ -258,6 +259,7 @@
res = IPACM_FAILURE;
goto fail;
}
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1);
/* ipv6 case */
if (m_filtering.DeleteFilteringHdls(&software_routing_fl_rule_hdl[1],
@@ -267,6 +269,7 @@
res = IPACM_FAILURE;
goto fail;
}
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
softwarerouting_act = false;
#if 0
}
@@ -297,6 +300,7 @@
res = IPACM_FAILURE;
goto fail;
}
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, ip, 1);
softwarerouting_act = false;
}
#endif
@@ -754,7 +758,7 @@
}
else
{
- flt_rule_count_v4 += IPV4_DEFAULT_FILTERTING_RULES;
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPV4_DEFAULT_FILTERTING_RULES);
/* copy filter hdls */
for (int i = 0; i < IPV4_DEFAULT_FILTERTING_RULES; i++)
{
@@ -842,7 +846,7 @@
}
else
{
- flt_rule_count_v6 += IPV6_DEFAULT_FILTERTING_RULES;
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, IPV6_DEFAULT_FILTERTING_RULES);
/* copy filter hdls */
for (int i = 0;
i < IPV6_DEFAULT_FILTERTING_RULES;
diff --git a/ipacm/src/IPACM_IfaceManager.cpp b/ipacm/src/IPACM_IfaceManager.cpp
index d8998cb..4e6c438 100644
--- a/ipacm/src/IPACM_IfaceManager.cpp
+++ b/ipacm/src/IPACM_IfaceManager.cpp
@@ -225,6 +225,7 @@
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_CRADLE_WAN_MODE_SWITCH, lan);
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);
@@ -246,6 +247,7 @@
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6, ETH);
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN, ETH);
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6, ETH);
+ IPACM_EvtDispatcher::registr(IPA_CRADLE_WAN_MODE_SWITCH, ETH);
IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, ETH);
IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, ETH);
IPACMDBG_H("ipa_LAN (%s):ipa_index (%d) instance open/registr ok\n", ETH->dev_name, ETH->ipa_if_num);
@@ -269,6 +271,7 @@
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6, odu);
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN, odu);
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6, odu);
+ IPACM_EvtDispatcher::registr(IPA_CRADLE_WAN_MODE_SWITCH, odu);
IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, odu);
IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, odu);
IPACMDBG("ipa_LAN (%s):ipa_index (%d) instance open/registr ok\n", odu->dev_name, odu->ipa_if_num);
@@ -319,6 +322,7 @@
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_CRADLE_WAN_MODE_SWITCH, wl);
IPACM_EvtDispatcher::registr(IPA_WLAN_LINK_DOWN_EVENT, wl);
IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, wl);
#ifndef FEATURE_IPA_ANDROID
diff --git a/ipacm/src/IPACM_Lan.cpp b/ipacm/src/IPACM_Lan.cpp
index 8716645..25fbe2c 100644
--- a/ipacm/src/IPACM_Lan.cpp
+++ b/ipacm/src/IPACM_Lan.cpp
@@ -168,6 +168,22 @@
memset(ipv6_prefix_flt_rule_hdl, 0, NUM_IPV6_PREFIX_FLT_RULE * sizeof(uint32_t));
memset(ipv6_icmp_flt_rule_hdl, 0, NUM_IPV6_ICMP_FLT_RULE * sizeof(uint32_t));
+#ifdef FEATURE_ETH_BRIDGE_LE
+ exp_index_v4 = IPV4_DEFAULT_FILTERTING_RULES + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPACM_Iface::ipacmcfg->ipa_num_private_subnet;
+ exp_index_v6 = IPV6_DEFAULT_FILTERTING_RULES + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + NUM_IPV6_ICMP_FLT_RULE + NUM_IPV6_PREFIX_FLT_RULE;
+#else
+#ifdef CT_OPT
+ exp_index_v4 = IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + NUM_TCP_CTL_FLT_RULE + IPACM_Iface::ipacmcfg->ipa_num_private_subnet;
+ exp_index_v6 = IPV6_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + NUM_IPV6_ICMP_FLT_RULE + NUM_IPV6_PREFIX_FLT_RULE;
+#else
+ exp_index_v4 = IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet;
+ exp_index_v6 = IPV6_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + NUM_IPV6_ICMP_FLT_RULE + NUM_IPV6_PREFIX_FLT_RULE;
+#endif
+#ifdef FEATURE_IPA_ANDROID
+ exp_index_v4 = exp_index_v4 - IPACM_Iface::ipacmcfg->ipa_num_private_subnet + IPA_MAX_PRIVATE_SUBNET_ENTRIES;
+#endif
+#endif
+
/* ODU routing table initilization */
if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF)
{
@@ -342,6 +358,21 @@
//IPACMDBG_H("Posting event:%d\n", evt_data.event);
IPACM_EvtDispatcher::PostEvt(&evt_data);
}
+#ifndef FEATURE_IPA_ANDROID
+ if(rx_prop != NULL)
+ {
+ if(IPACM_Iface::ipacmcfg->getFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4) != 0)
+ {
+ IPACMDBG_DMESG("### WARNING ### num ipv4 flt rules on client %d is not expected: %d expected value: 0",
+ rx_prop->rx[0].src_pipe, IPACM_Iface::ipacmcfg->getFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4));
+ }
+ if(IPACM_Iface::ipacmcfg->getFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6) != 0)
+ {
+ IPACMDBG_DMESG("### WARNING ### num ipv6 flt rules on client %d is not expected: %d expected value: 0",
+ rx_prop->rx[0].src_pipe, IPACM_Iface::ipacmcfg->getFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6));
+ }
+ }
+#endif
delete this;
}
break;
@@ -740,6 +771,27 @@
}
break;
+ case IPA_CRADLE_WAN_MODE_SWITCH:
+ {
+ IPACMDBG_H("Received IPA_CRADLE_WAN_MODE_SWITCH event.\n");
+ ipacm_event_cradle_wan_mode* wan_mode = (ipacm_event_cradle_wan_mode*)param;
+ if(wan_mode == NULL)
+ {
+ IPACMERR("Event data is empty.\n");
+ return;
+ }
+
+ if(wan_mode->cradle_wan_mode == BRIDGE)
+ {
+ handle_cradle_wan_mode_switch(true);
+ }
+ else
+ {
+ handle_cradle_wan_mode_switch(false);
+ }
+ }
+ break;
+
default:
break;
}
@@ -759,20 +811,6 @@
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;
-#else
- flt_rule_count_v4 = IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR
- + 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)
{
@@ -789,6 +827,7 @@
close(fd);
return IPACM_FAILURE;
}
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, num_wan_ul_fl_rule_v4);
memset(wan_ul_fl_rule_hdl_v4, 0, MAX_WAN_UL_FILTER_RULES * sizeof(uint32_t));
num_wan_ul_fl_rule_v4 = 0;
@@ -819,6 +858,7 @@
close(fd);
return IPACM_FAILURE;
}
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1);
}
close(fd);
@@ -1091,8 +1131,7 @@
free(m_pFilteringTable);
return IPACM_FAILURE;
}
-
- flt_rule_count_v4 += IPACM_Iface::ipacmcfg->ipa_num_private_subnet;
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
/* copy filter rule hdls */
for (i = 0; i < IPACM_Iface::ipacmcfg->ipa_num_private_subnet; i++)
@@ -1156,7 +1195,14 @@
flt_rule_entry.at_rear = true;
flt_rule_entry.flt_rule_hdl = -1;
flt_rule_entry.status = -1;
- flt_rule_entry.rule.action = IPA_PASS_TO_SRC_NAT; //IPA_PASS_TO_ROUTING
+ if(IPACM_Wan::cradle_backhaul_is_wan_bridge == true)
+ {
+ flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
+ }
+ else
+ {
+ flt_rule_entry.rule.action = IPA_PASS_TO_SRC_NAT; //IPA_PASS_TO_ROUTING
+ }
flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.hdl;
memcpy(&flt_rule_entry.rule.attrib,
@@ -1176,6 +1222,7 @@
}
else
{
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1);
IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n",
m_pFilteringTable->rules[0].flt_rule_hdl,
m_pFilteringTable->rules[0].status);
@@ -1243,6 +1290,7 @@
}
else
{
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status);
}
@@ -2372,6 +2420,7 @@
res = IPACM_FAILURE;
goto fail;
}
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPV4_DEFAULT_FILTERTING_RULES);
#ifdef FEATURE_ETH_BRIDGE_LE
for(i=0; i<IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; i++)
{
@@ -2383,13 +2432,8 @@
res = IPACM_FAILURE;
goto fail;
}
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPA_LAN_TO_LAN_MAX_WLAN_CLIENT);
#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)
@@ -2398,6 +2442,7 @@
res = IPACM_FAILURE;
goto fail;
}
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, NUM_TCP_CTL_FLT_RULE);
#endif
for(i=0; i<MAX_OFFLOAD_PAIR; i++)
{
@@ -2407,6 +2452,7 @@
res = IPACM_FAILURE;
goto fail;
}
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1);
}
IPACMDBG_H("Deleted lan2lan IPv4 flt rules.\n");
#endif
@@ -2426,6 +2472,7 @@
res = IPACM_FAILURE;
goto fail;
}
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES);
#else
if (m_filtering.DeleteFilteringHdls(private_fl_rule_hdl, IPA_IP_v4, IPACM_Iface::ipacmcfg->ipa_num_private_subnet) == false)
{
@@ -2433,20 +2480,28 @@
res = IPACM_FAILURE;
goto fail;
}
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
#endif
}
IPACMDBG_H("Finished delete default iface ipv4 filtering rules \n ");
if (ip_type != IPA_IP_v4 && rx_prop != NULL)
{
- if (m_filtering.DeleteFilteringHdls(dft_v6fl_rule_hdl,
- IPA_IP_v6,
- (IPV6_DEFAULT_FILTERTING_RULES + IPV6_DEFAULT_LAN_FILTERTING_RULES)) == false)
+ 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;
+ }
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, NUM_IPV6_ICMP_FLT_RULE);
+
+ if (m_filtering.DeleteFilteringHdls(dft_v6fl_rule_hdl, IPA_IP_v6, IPV6_DEFAULT_FILTERTING_RULES) == false)
{
IPACMERR("Error Adding RuleTable(1) to Filtering, aborting...\n");
res = IPACM_FAILURE;
goto fail;
}
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, IPV6_DEFAULT_FILTERTING_RULES);
#ifdef FEATURE_ETH_BRIDGE_LE
for(i=0; i<IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; i++)
{
@@ -2458,6 +2513,7 @@
res = IPACM_FAILURE;
goto fail;
}
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, IPA_LAN_TO_LAN_MAX_WLAN_CLIENT);
#endif
#ifndef FEATURE_ETH_BRIDGE_LE
#ifdef CT_OPT
@@ -2467,6 +2523,7 @@
res = IPACM_FAILURE;
goto fail;
}
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, NUM_TCP_CTL_FLT_RULE);
#endif
for(i=0; i<MAX_OFFLOAD_PAIR; i++)
{
@@ -2476,6 +2533,7 @@
res = IPACM_FAILURE;
goto fail;
}
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
}
IPACMDBG_H("Deleted lan2lan IPv6 flt rules.\n");
#endif
@@ -2652,7 +2710,7 @@
ipa_ioc_add_flt_rule *pFilteringTable;
ipa_fltr_installed_notif_req_msg_v01 flt_index;
int fd;
- int i;
+ int i, index;
IPACMDBG_H("Set extended property rules in LAN\n");
@@ -2672,6 +2730,13 @@
if (0 == fd)
{
IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
+ return IPACM_FAILURE;
+ }
+ if (prop->num_ext_props > MAX_WAN_UL_FILTER_RULES)
+ {
+ IPACMERR("number of modem UL rules > MAX_WAN_UL_FILTER_RULES, aborting...\n");
+ close(fd);
+ return IPACM_FAILURE;
}
memset(&flt_index, 0, sizeof(flt_index));
@@ -2722,6 +2787,21 @@
goto fail;
}
+ index = IPACM_Iface::ipacmcfg->getFltRuleCount(rx_prop->rx[0].src_pipe, iptype);
+
+#ifndef FEATURE_IPA_ANDROID
+ if(iptype == IPA_IP_v4 && index != exp_index_v4)
+ {
+ IPACMDBG_DMESG("### WARNING ### num flt rules for IPv4 on client %d is not expected: %d expected value: %d",
+ rx_prop->rx[0].src_pipe, index, exp_index_v4);
+ }
+ if(iptype == IPA_IP_v6 && index != exp_index_v6)
+ {
+ IPACMDBG_DMESG("### WARNING ### num flt rules for IPv6 on client %d is not expected: %d expected value: %d",
+ rx_prop->rx[0].src_pipe, index, exp_index_v6);
+ }
+#endif
+
for(cnt=0; cnt<prop->num_ext_props; cnt++)
{
memcpy(&flt_rule_entry.rule.eq_attrib,
@@ -2730,18 +2810,10 @@
flt_rule_entry.rule.rt_tbl_idx = prop->prop[cnt].rt_tbl_idx;
memcpy(&pFilteringTable->rules[cnt], &flt_rule_entry, sizeof(flt_rule_entry));
- if(iptype == IPA_IP_v4)
- {
- IPACMDBG_H("Filtering rule %d has index %d\n", cnt, flt_rule_count_v4);
- flt_index.filter_index_list[cnt].filter_index = flt_rule_count_v4;
- flt_rule_count_v4++;
- }
- if(iptype == IPA_IP_v6)
- {
- IPACMDBG_H("Filtering rule %d has index %d\n", cnt, flt_rule_count_v6);
- flt_index.filter_index_list[cnt].filter_index = flt_rule_count_v6;
- flt_rule_count_v6++;
- }
+ IPACMDBG_H("Modem UL filtering rule %d has index %d\n", cnt, index);
+ flt_index.filter_index_list[cnt].filter_index = index;
+ index++;
+
flt_index.filter_index_list[cnt].filter_handle = prop->prop[cnt].filter_hdl;
}
@@ -2767,6 +2839,7 @@
wan_ul_fl_rule_hdl_v4[num_wan_ul_fl_rule_v4] = pFilteringTable->rules[i].flt_rule_hdl;
num_wan_ul_fl_rule_v4++;
}
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, iptype, pFilteringTable->num_rules);
}
else if(iptype == IPA_IP_v6)
{
@@ -2775,6 +2848,7 @@
wan_ul_fl_rule_hdl_v6[num_wan_ul_fl_rule_v6] = pFilteringTable->rules[i].flt_rule_hdl;
num_wan_ul_fl_rule_v6++;
}
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, iptype, pFilteringTable->num_rules);
}
else
{
@@ -2800,21 +2874,13 @@
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)
{
close(fd);
return IPACM_FAILURE;
}
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, NUM_IPV6_PREFIX_FLT_RULE);
if(is_sta_mode == false)
{
@@ -2832,6 +2898,7 @@
close(fd);
return IPACM_FAILURE;
}
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, num_wan_ul_fl_rule_v6);
memset(wan_ul_fl_rule_hdl_v6, 0, MAX_WAN_UL_FILTER_RULES * sizeof(uint32_t));
num_wan_ul_fl_rule_v6 = 0;
@@ -2863,6 +2930,7 @@
close(fd);
return IPACM_FAILURE;
}
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
}
close(fd);
@@ -3188,7 +3256,7 @@
}
else
{
- flt_rule_count_v4 += MAX_OFFLOAD_PAIR;
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, MAX_OFFLOAD_PAIR);
/* copy filter rule hdls */
for (int i = 0; i < MAX_OFFLOAD_PAIR; i++)
{
@@ -3239,7 +3307,7 @@
}
else
{
- flt_rule_count_v6 += MAX_OFFLOAD_PAIR;
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, MAX_OFFLOAD_PAIR);
/* copy filter rule hdls */
for (int i = 0; i < MAX_OFFLOAD_PAIR; i++)
{
@@ -4083,17 +4151,17 @@
{
for(i=0; i<NUM_TCP_CTL_FLT_RULE; i++)
{
- flt_rule_count_v4++;
tcp_ctl_flt_rule_hdl_v4[i] = pFilteringTable->rules[i].flt_rule_hdl;
}
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, iptype, NUM_TCP_CTL_FLT_RULE);
}
else
{
for(i=0; i<NUM_TCP_CTL_FLT_RULE; i++)
{
- flt_rule_count_v6++;
tcp_ctl_flt_rule_hdl_v6[i] = pFilteringTable->rules[i].flt_rule_hdl;
}
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, iptype, NUM_TCP_CTL_FLT_RULE);
}
}
@@ -4167,7 +4235,7 @@
}
else
{
- flt_rule_count_v4 += IPA_MAX_PRIVATE_SUBNET_ENTRIES;
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES);
/* copy filter rule hdls */
for (int i = 0; i < IPA_MAX_PRIVATE_SUBNET_ENTRIES; i++)
{
@@ -4333,9 +4401,9 @@
}
else
{
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
ipv6_prefix_flt_rule_hdl[0] = flt_rule->rules[0].flt_rule_hdl;
IPACMDBG_H("IPv6 prefix filter rule HDL:0x%x\n", ipv6_prefix_flt_rule_hdl[0]);
- flt_rule_count_v6++;
free(flt_rule);
}
}
@@ -4390,9 +4458,9 @@
}
else
{
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
ipv6_icmp_flt_rule_hdl[0] = flt_rule->rules[0].flt_rule_hdl;
IPACMDBG_H("IPv6 icmp filter rule HDL:0x%x\n", ipv6_icmp_flt_rule_hdl[0]);
- flt_rule_count_v6++;
free(flt_rule);
}
}
@@ -4492,7 +4560,7 @@
}
else
{
- flt_rule_count_v4 += IPA_LAN_TO_LAN_MAX_WLAN_CLIENT;
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, iptype, IPA_LAN_TO_LAN_MAX_WLAN_CLIENT);
/* copy filter rule hdls */
for (int i = 0; i < IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; i++)
{
@@ -4544,7 +4612,7 @@
}
else
{
- flt_rule_count_v6 += IPA_LAN_TO_LAN_MAX_WLAN_CLIENT;
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, iptype, IPA_LAN_TO_LAN_MAX_WLAN_CLIENT);
/* copy filter rule hdls */
for (int i = 0; i < IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; i++)
{
@@ -5437,5 +5505,85 @@
return IPACM_SUCCESS;
}
+int IPACM_Lan::handle_cradle_wan_mode_switch(bool is_wan_bridge_mode)
+{
+ struct ipa_flt_rule_mdfy flt_rule_entry;
+ int len = 0;
+ ipa_ioc_mdfy_flt_rule *m_pFilteringTable;
+
+ IPACMDBG_H("Handle wan mode swtich: is wan bridge mode?%d\n", is_wan_bridge_mode);
+
+ if (rx_prop == NULL)
+ {
+ IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
+ return IPACM_SUCCESS;
+ }
+
+ len = sizeof(struct ipa_ioc_mdfy_flt_rule) + (1 * sizeof(struct ipa_flt_rule_mdfy));
+ m_pFilteringTable = (struct ipa_ioc_mdfy_flt_rule *)calloc(1, len);
+ if (m_pFilteringTable == NULL)
+ {
+ PERROR("Error Locate ipa_ioc_mdfy_flt_rule memory...\n");
+ return IPACM_FAILURE;
+ }
+
+ m_pFilteringTable->commit = 1;
+ m_pFilteringTable->ip = IPA_IP_v4;
+ m_pFilteringTable->num_rules = (uint8_t)1;
+
+ IPACMDBG_H("Retrieving routing hanle for table: %s\n",
+ IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.name);
+ if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_wan_v4))
+ {
+ IPACMERR("m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_wan_v4=0x%p) Failed.\n",
+ &IPACM_Iface::ipacmcfg->rt_tbl_wan_v4);
+ free(m_pFilteringTable);
+ return IPACM_FAILURE;
+ }
+ IPACMDBG_H("Routing handle for table: %d\n", IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.hdl);
+
+
+ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_mdfy)); // Zero All Fields
+ flt_rule_entry.status = -1;
+ flt_rule_entry.rule_hdl = lan_wan_fl_rule_hdl[0];
+
+ flt_rule_entry.rule.retain_hdr = 0;
+ flt_rule_entry.rule.to_uc = 0;
+ flt_rule_entry.rule.eq_attrib_type = 0;
+ if(is_wan_bridge_mode)
+ {
+ flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
+ }
+ else
+ {
+ flt_rule_entry.rule.action = IPA_PASS_TO_SRC_NAT;
+ }
+ flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.hdl;
+
+ memcpy(&flt_rule_entry.rule.attrib,
+ &rx_prop->rx[0].attrib,
+ sizeof(flt_rule_entry.rule.attrib));
+
+ flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
+ flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x0;
+ flt_rule_entry.rule.attrib.u.v4.dst_addr = 0x0;
+
+ memcpy(&m_pFilteringTable->rules[0], &flt_rule_entry, sizeof(flt_rule_entry));
+ if (false == m_filtering.ModifyFilteringRule(m_pFilteringTable))
+ {
+ IPACMERR("Error Modifying RuleTable(0) to Filtering, aborting...\n");
+ free(m_pFilteringTable);
+ return IPACM_FAILURE;
+ }
+ else
+ {
+ IPACMDBG_H("flt rule hdl = %d, status = %d\n",
+ m_pFilteringTable->rules[0].rule_hdl,
+ m_pFilteringTable->rules[0].status);
+ }
+ free(m_pFilteringTable);
+ return IPACM_SUCCESS;
+}
+
diff --git a/ipacm/src/IPACM_Main.cpp b/ipacm/src/IPACM_Main.cpp
index 0aef584..3cc58e1 100644
--- a/ipacm/src/IPACM_Main.cpp
+++ b/ipacm/src/IPACM_Main.cpp
@@ -611,16 +611,22 @@
case WLAN_SWITCH_TO_SCC:
IPACMDBG_H("Received WLAN_SWITCH_TO_SCC\n");
- IPACM_Iface::ipacmcfg->isMCC_Mode = false;
- evt_data.event = IPA_WLAN_SWITCH_TO_SCC;
- break;
-
+ if (IPACM_Iface::ipacmcfg->isMCC_Mode == true)
+ {
+ IPACM_Iface::ipacmcfg->isMCC_Mode = false;
+ evt_data.event = IPA_WLAN_SWITCH_TO_SCC;
+ break;
+ }
+ continue;
case WLAN_SWITCH_TO_MCC:
IPACMDBG_H("Received WLAN_SWITCH_TO_MCC\n");
- IPACM_Iface::ipacmcfg->isMCC_Mode = true;
- evt_data.event = IPA_WLAN_SWITCH_TO_MCC;
- break;
-
+ if (IPACM_Iface::ipacmcfg->isMCC_Mode == false)
+ {
+ IPACM_Iface::ipacmcfg->isMCC_Mode == true;
+ evt_data.event = IPA_WLAN_SWITCH_TO_MCC;
+ break;
+ }
+ continue;
default:
IPACMDBG_H("Unhandled message type: %d\n", event_hdr.msg_type);
continue;
diff --git a/ipacm/src/IPACM_Netlink.cpp b/ipacm/src/IPACM_Netlink.cpp
index 9db578c..13b1d6e 100644
--- a/ipacm/src/IPACM_Netlink.cpp
+++ b/ipacm/src/IPACM_Netlink.cpp
@@ -610,7 +610,7 @@
int ret_val, mask_value, mask_index, mask_value_v6;
struct nlmsghdr *nlh = (struct nlmsghdr *)buffer;
- uint32_t if_ipv4_addr =0, if_ipipv4_addr_mask =0, temp =0;
+ uint32_t if_ipv4_addr =0, if_ipipv4_addr_mask =0, temp =0, if_ipv4_addr_gw =0;
ipacm_cmd_q_data evt_data;
ipacm_event_data_all *data_all;
@@ -996,17 +996,20 @@
IPACM_EVENT_COPY_ADDR_v4( if_ipv4_addr, msg_ptr->nl_route_info.attr_info.dst_addr);
IPACM_EVENT_COPY_ADDR_v4( if_ipipv4_addr_mask, msg_ptr->nl_route_info.attr_info.dst_addr);
+ IPACM_EVENT_COPY_ADDR_v4( if_ipv4_addr_gw, msg_ptr->nl_route_info.attr_info.gateway_addr);
evt_data.event = IPA_ROUTE_ADD_EVENT;
data_addr->if_index = msg_ptr->nl_route_info.attr_info.oif_index;
data_addr->iptype = IPA_IP_v4;
data_addr->ipv4_addr = ntohl(if_ipv4_addr);
+ data_addr->ipv4_addr_gw = ntohl(if_ipv4_addr_gw);
data_addr->ipv4_addr_mask = ntohl(if_ipipv4_addr_mask);
- IPACMDBG_H("Posting IPA_ROUTE_ADD_EVENT with if index:%d, ipv4 addr:0x%x and maxk: 0x%x\n",
+ IPACMDBG_H("Posting IPA_ROUTE_ADD_EVENT with if index:%d, ipv4 addr:0x%x, mask: 0x%x and gw: 0x%x\n",
data_addr->if_index,
data_addr->ipv4_addr,
- data_addr->ipv4_addr_mask);
+ data_addr->ipv4_addr_mask,
+ data_addr->ipv4_addr_gw);
evt_data.evt_data = data_addr;
IPACM_EvtDispatcher::PostEvt(&evt_data);
/* finish command queue */
diff --git a/ipacm/src/IPACM_Wan.cpp b/ipacm/src/IPACM_Wan.cpp
index 92b4a5e..3527f13 100644
--- a/ipacm/src/IPACM_Wan.cpp
+++ b/ipacm/src/IPACM_Wan.cpp
@@ -66,6 +66,7 @@
int IPACM_Wan::num_ipv6_modem_pdn = 0;
bool IPACM_Wan::embms_is_on = false;
+bool IPACM_Wan::cradle_backhaul_is_wan_bridge = false;
uint32_t IPACM_Wan::backhaul_ipv6_prefix[2];
@@ -90,6 +91,7 @@
m_is_sta_mode = is_sta_mode;
wan_v4_addr_set = false;
+ wan_v4_addr_gw_set = false;
active_v4 = false;
active_v6 = false;
header_set_v4 = false;
@@ -352,6 +354,7 @@
}
else
{
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
ipv6_dest_flt_rule_hdl[num_ipv6_dest_flt_rule] = flt_rule->rules[0].flt_rule_hdl;
IPACMDBG_H("IPv6 dest filter rule %d HDL:0x%x\n", num_ipv6_dest_flt_rule, ipv6_dest_flt_rule_hdl[num_ipv6_dest_flt_rule]);
num_ipv6_dest_flt_rule++;
@@ -501,7 +504,66 @@
case IPA_CFG_CHANGE_EVENT:
{
- if ( (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat != ipa_if_cate) &&
+ if ( (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ipa_if_cate) &&
+ (m_is_sta_mode ==ECM_WAN))
+ {
+ IPACMDBG_H("Received IPA_CFG_CHANGE_EVENT and category did not change(wan_mode:%d)\n", m_is_sta_mode);
+ IPACMDBG_H("Now the cradle wan mode is %d.\n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode);
+ if(is_default_gateway == true)
+ {
+ if(cradle_backhaul_is_wan_bridge == false && IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode == BRIDGE)
+ {
+ IPACMDBG_H("Cradle wan mode switch to bridge mode.\n");
+ cradle_backhaul_is_wan_bridge = true;
+ }
+ else if(cradle_backhaul_is_wan_bridge == true && IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode == ROUTER)
+ {
+ IPACMDBG_H("Cradle wan mode switch to router mode.\n");
+ cradle_backhaul_is_wan_bridge = false;
+ }
+ else
+ {
+ IPACMDBG_H("No cradle mode switch, return.\n");
+ return;
+ }
+ /* post wan mode change event to LAN/WLAN */
+ if(IPACM_Wan::wan_up == true)
+ {
+ IPACMDBG_H("This interface is default GW.\n");
+ ipacm_cmd_q_data evt_data;
+ memset(&evt_data, 0, sizeof(evt_data));
+
+ ipacm_event_cradle_wan_mode *data_wan_mode = NULL;
+ data_wan_mode = (ipacm_event_cradle_wan_mode *)malloc(sizeof(ipacm_event_cradle_wan_mode));
+ if(data_wan_mode == NULL)
+ {
+ IPACMERR("unable to allocate memory.\n");
+ return;
+ }
+ data_wan_mode->cradle_wan_mode = IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode;
+ evt_data.event = IPA_CRADLE_WAN_MODE_SWITCH;
+ evt_data.evt_data = data_wan_mode;
+ IPACMDBG_H("Posting IPA_CRADLE_WAN_MODE_SWITCH event.\n");
+ IPACM_EvtDispatcher::PostEvt(&evt_data);
+ }
+ /* update the firewall flt rule actions */
+ if(active_v4)
+ {
+ del_dft_firewall_rules(IPA_IP_v4);
+ config_dft_firewall_rules(IPA_IP_v4);
+ }
+ if(active_v6)
+ {
+ del_dft_firewall_rules(IPA_IP_v6);
+ config_dft_firewall_rules(IPA_IP_v6);
+ }
+ }
+ else
+ {
+ IPACMDBG_H("This interface is not default GW, ignore.\n");
+ }
+ }
+ else if ( (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat != ipa_if_cate) &&
(m_is_sta_mode ==ECM_WAN))
{
IPACMDBG_H("Received IPA_CFG_CHANGE_EVENT and category changed(wan_mode:%d)\n", m_is_sta_mode);
@@ -611,8 +673,11 @@
/* The special below condition is to handle default gateway */
if ((data->iptype == IPA_IP_v4) && (active_v4 == false) && (ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX))
{
- IPACMDBG_H("adding routing table(upstream), dev (%s) ip-type(%d)\n", dev_name,data->iptype);
+// wan_v4_addr_gw = data->ipv4_addr_gw; /* android requires CnE change too */
+// wan_v4_addr_gw_set = true;
+ IPACMDBG_H("adding routing table, dev (%s) ip-type(%d), default gw (%x)\n", dev_name,data->iptype, wan_v4_addr_gw);
handle_route_add_evt(data->iptype);
+
}
else if ((data->iptype == IPA_IP_v6) && (active_v6 == false) && (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX))
{
@@ -626,6 +691,7 @@
{
IPACMDBG_H("Received v4 IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT for other iface (%s)\n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name);
IPACMDBG_H("need clean default v4 route (dst:0.0.0.0) for old iface (%s)\n", dev_name);
+// wan_v4_addr_gw_set = false; /* android requires CnE change too */
if(m_is_sta_mode == Q6_WAN)
{
del_wan_firewall_rule(IPA_IP_v4);
@@ -667,6 +733,8 @@
IPACMDBG_H("Received IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT\n");
if ((data->iptype == IPA_IP_v4) && (active_v4 == true))
{
+ IPACMDBG_H("get del default v4 route (dst:0.0.0.0)\n");
+// wan_v4_addr_gw_set = false; /* android requires CnE change too */
if(m_is_sta_mode == Q6_WAN)
{
del_wan_firewall_rule(IPA_IP_v4);
@@ -711,7 +779,11 @@
if ((data->iptype == IPA_IP_v4) && (!data->ipv4_addr) && (!data->ipv4_addr_mask) && (active_v4 == false)
&& (ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX))
{
- IPACMDBG_H("adding routing table, dev (%s) ip-type(%d)\n", dev_name,data->iptype);
+ wan_v4_addr_gw = data->ipv4_addr_gw;
+ wan_v4_addr_gw_set = true;
+ IPACMDBG_H("adding routing table, dev (%s) ip-type(%d), default gw (%x)\n", dev_name,data->iptype, wan_v4_addr_gw);
+ /* Check & construct STA header */
+ handle_sta_header_add_evt();
handle_route_add_evt(data->iptype);
}
else if ((data->iptype == IPA_IP_v6) &&
@@ -732,6 +804,7 @@
IPACMDBG_H("ipv4 addr 0x%x\n", data->ipv4_addr);
IPACMDBG_H("ipv4 addr mask 0x%x\n", data->ipv4_addr_mask);
IPACMDBG_H("need clean default v4 route (dst:0.0.0.0) for old iface (%s)\n", dev_name);
+ wan_v4_addr_gw_set = false;
if(m_is_sta_mode == Q6_WAN)
{
del_wan_firewall_rule(IPA_IP_v4);
@@ -774,6 +847,7 @@
if ((data->iptype == IPA_IP_v4) && (!data->ipv4_addr) && (!data->ipv4_addr_mask) && (active_v4 == true))
{
IPACMDBG_H("get del default v4 route (dst:0.0.0.0)\n");
+ wan_v4_addr_gw_set = false;
if(m_is_sta_mode == Q6_WAN)
{
del_wan_firewall_rule(IPA_IP_v4);
@@ -817,7 +891,6 @@
if (m_is_sta_mode == WLAN_WAN)
{
- handle_header_add_evt(ext_router_mac_addr);
if (data->iptype == IPA_IP_v4 && data->ipv4_addr == wan_v4_addr)
{
IPACMDBG_H("Ignore IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT in STA mode\n");
@@ -853,18 +926,17 @@
return;
}
- handle_header_add_evt(data->mac_addr);
-
handle_wan_hdr_init(data->mac_addr);
- IPACMDBG_H("construct wan header and route rules \n");
+ IPACMDBG_H("construct wan-client header and route rules \n");
/* Associate with IP and construct RT-rule */
if (handle_wan_client_ipaddr(data) == IPACM_FAILURE)
{
return;
}
handle_wan_client_route_rule(data->mac_addr, data->iptype);
+ /* Check & construct STA header */
+ handle_sta_header_add_evt();
return;
-
}
}
break;
@@ -1027,6 +1099,14 @@
if (m_is_sta_mode !=Q6_WAN)
{
IPACM_Wan::backhaul_is_sta_mode = true;
+ if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode == BRIDGE)
+ {
+ IPACM_Wan::cradle_backhaul_is_wan_bridge = true;
+ }
+ else
+ {
+ IPACM_Wan::cradle_backhaul_is_wan_bridge = false;
+ }
if((iptype==IPA_IP_v4) && (header_set_v4 != true))
{
header_partial_default_wan_v4 = true;
@@ -1064,7 +1144,7 @@
return IPACM_FAILURE;
}
}
-
+#if 0
for (cnt=0; cnt<tx_prop->num_tx_props; cnt++)
{
if(tx_prop->tx[cnt].ip==iptype)
@@ -1110,6 +1190,7 @@
}
}
}
+#endif
rt_rule = (struct ipa_ioc_add_rt_rule *)
calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
@@ -1142,29 +1223,16 @@
continue;
}
+ /* use the STA-header handler */
if (iptype == IPA_IP_v4)
{
strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.name);
+ rt_rule_entry->rule.hdr_hdl = hdr_hdl_sta_v4;
}
else
{
strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_v6.name);
- }
-
- if (tx_prop->tx[tx_index].hdr_name != NULL)
- {
- IPACMDBG_H(" TX- header hdl %s \n", tx_prop->tx[tx_index].hdr_name);
- memset(&sRetHeader, 0, sizeof(sRetHeader));
- strncpy(sRetHeader.name,
- tx_prop->tx[tx_index].hdr_name,
- sizeof(tx_prop->tx[tx_index].hdr_name));
- if (false == m_header.GetHeaderHandle(&sRetHeader))
- {
- IPACMERR("\n ioctl failed\n");
- free(rt_rule);
- return IPACM_FAILURE;
- }
- rt_rule_entry->rule.hdr_hdl = sRetHeader.hdl;
+ rt_rule_entry->rule.hdr_hdl = hdr_hdl_sta_v6;
}
if(IPACM_Iface::ipacmcfg->isMCC_Mode == true)
@@ -1353,233 +1421,70 @@
}
/* construct complete ethernet header */
-int IPACM_Wan::handle_header_add_evt(uint8_t *mac_addr)
+int IPACM_Wan::handle_sta_header_add_evt()
{
- #define WAN_IFACE_INDEX_LEN 2
-
- uint32_t tx_index,cnt;
- int res = IPACM_SUCCESS, len = 0;
- char index[WAN_IFACE_INDEX_LEN];
- struct ipa_ioc_copy_hdr sCopyHeader;
- struct ipa_ioc_add_hdr *pHeaderDescriptor = NULL;
-
- /* start of adding header */
-
- IPACMDBG_H("Received Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
- mac_addr[0], mac_addr[1], mac_addr[2],
- mac_addr[3], mac_addr[4], mac_addr[5]);
-
+ int res = IPACM_SUCCESS, index = IPACM_INVALID_INDEX;
if((header_set_v4 == true) || (header_set_v6 == true))
{
IPACMDBG_H("Already add STA full header\n");
return IPACM_SUCCESS;
}
- /* add header to IPA */
- len = sizeof(struct ipa_ioc_add_hdr) + (1 * sizeof(struct ipa_hdr_add));
- pHeaderDescriptor = (struct ipa_ioc_add_hdr *)calloc(1, len);
- if (pHeaderDescriptor == NULL)
+
+ /* checking if the ipv4 same as default route */
+ if(wan_v4_addr_gw_set)
{
- IPACMERR("calloc failed to allocate pHeaderDescriptor\n");
- return IPACM_FAILURE;
- }
-
- /* copy partial header for v4 */
- for (cnt=0; cnt<tx_prop->num_tx_props; cnt++)
- {
- if(tx_prop->tx[cnt].ip==IPA_IP_v4)
- {
- memset(&sCopyHeader, 0, sizeof(sCopyHeader));
- memcpy(sCopyHeader.name,
- tx_prop->tx[cnt].hdr_name,
- sizeof(sCopyHeader.name));
-
- IPACMDBG_H("header name: %s from tx: %d\n", sCopyHeader.name,cnt);
- if (m_header.CopyHeader(&sCopyHeader) == false)
- {
- IPACMERR("ioctl copy header failed");
- res = IPACM_FAILURE;
- goto fail;
- }
-
- if(sCopyHeader.is_eth2_ofst_valid == false)
- {
- eth2_ofst_v4 = 0;
- }
- else
- {
- eth2_ofst_v4 = sCopyHeader.eth2_ofst;
- }
-
- IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial);
- if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE)
- {
- IPACMERR("header oversize\n");
- res = IPACM_FAILURE;
- goto fail;
- }
- else
- {
- memcpy(pHeaderDescriptor->hdr[0].hdr,
- sCopyHeader.hdr,
- sCopyHeader.hdr_len);
- }
-
- /* copy client mac_addr to partial header */
- memcpy(&pHeaderDescriptor->hdr[0].hdr[eth2_ofst_v4], mac_addr,
- IPA_MAC_ADDR_SIZE); /* only copy 6 bytes mac-address */
-
- pHeaderDescriptor->commit = true;
- pHeaderDescriptor->num_hdrs = 1;
-
- memset(pHeaderDescriptor->hdr[0].name, 0,
- sizeof(pHeaderDescriptor->hdr[0].name));
-
- snprintf(index,sizeof(index), "%d", ipa_if_num);
- strlcpy(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name));
- if ( strlcat(pHeaderDescriptor->hdr[0].name, IPA_WAN_PARTIAL_HDR_NAME_v4, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX)
- {
- IPACMERR(" header name construction failed exceed length (%d)\n", strlen(pHeaderDescriptor->hdr[0].name));
- res = IPACM_FAILURE;
- goto fail;
- }
-
- pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len;
- pHeaderDescriptor->hdr[0].hdr_hdl = -1;
- pHeaderDescriptor->hdr[0].is_partial = 0;
- pHeaderDescriptor->hdr[0].status = -1;
-
- if (m_header.AddHeader(pHeaderDescriptor) == false ||
- pHeaderDescriptor->hdr[0].status != 0)
- {
- IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status);
- res = IPACM_FAILURE;
- goto fail;
- }
- else
- {
- hdr_hdl_sta_v4 = pHeaderDescriptor->hdr[0].hdr_hdl;
- header_set_v4 = true;
- IPACMDBG_H("add full header name: %s (%x)\n", pHeaderDescriptor->hdr[0].name, pHeaderDescriptor->hdr[0].hdr_hdl);
- }
-
- /* copy ipv4 full header to each TX endpoint property*/
- for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
- {
- if(tx_prop->tx[tx_index].ip==IPA_IP_v4)
- {
- memcpy(tx_prop->tx[tx_index].hdr_name, pHeaderDescriptor->hdr[0].name,
- sizeof(tx_prop->tx[tx_index].hdr_name));
- IPACMDBG_H("replace full header name: %s (%x) in tx:%d\n", tx_prop->tx[tx_index].hdr_name, pHeaderDescriptor->hdr[0].hdr_hdl,tx_index);
- }
- }
- break;
- }
- }
-
- /* copy partial header for v6 */
- for (cnt=0; cnt<tx_prop->num_tx_props; cnt++)
- {
- if(tx_prop->tx[cnt].ip == IPA_IP_v6)
- {
- IPACMDBG_H("Got partial v6-header name from %d tx props\n", cnt);
- memset(&sCopyHeader, 0, sizeof(sCopyHeader));
- memcpy(sCopyHeader.name,
- tx_prop->tx[cnt].hdr_name,
- sizeof(sCopyHeader.name));
-
- IPACMDBG_H("header name: %s from tx: %d\n", sCopyHeader.name,cnt);
- if (m_header.CopyHeader(&sCopyHeader) == false)
+ index = get_wan_client_index_ipv4(wan_v4_addr_gw);
+ if (index != IPACM_INVALID_INDEX)
+ {
+ IPACMDBG_H("Matched client index: %d\n", index);
+ IPACMDBG_H("Received Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
+ get_client_memptr(wan_client, index)->mac[0],
+ get_client_memptr(wan_client, index)->mac[1],
+ get_client_memptr(wan_client, index)->mac[2],
+ get_client_memptr(wan_client, index)->mac[3],
+ get_client_memptr(wan_client, index)->mac[4],
+ get_client_memptr(wan_client, index)->mac[5]);
+ if(get_client_memptr(wan_client, index)->ipv4_header_set)
{
- IPACMERR("ioctl copy header failed");
- res = IPACM_FAILURE;
- goto fail;
- }
-
- if(sCopyHeader.is_eth2_ofst_valid == false)
- {
- eth2_ofst_v6 = 0;
+ hdr_hdl_sta_v4 = get_client_memptr(wan_client, index)->hdr_hdl_v4;
+ header_set_v4 = true;
+ IPACMDBG_H("add full ipv4 header hdl: (%x)\n", get_client_memptr(wan_client, index)->hdr_hdl_v4);
}
else
{
- eth2_ofst_v6 = sCopyHeader.eth2_ofst;
+ IPACMERR(" wan-client got ipv4 however didn't construct complete ipv4 header \n");
+ return IPACM_FAILURE;
}
- IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial);
- if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE)
- {
- IPACMERR("header oversize\n");
- res = IPACM_FAILURE;
- goto fail;
- }
- else
- {
- memcpy(pHeaderDescriptor->hdr[0].hdr,
- sCopyHeader.hdr,
- sCopyHeader.hdr_len);
- }
- /* copy client mac_addr to partial header */
- memcpy(&pHeaderDescriptor->hdr[0].hdr[eth2_ofst_v6], mac_addr,
- IPA_MAC_ADDR_SIZE); /* only copy 6 bytes mac-address */
- pHeaderDescriptor->commit = true;
- pHeaderDescriptor->num_hdrs = 1;
-
- memset(pHeaderDescriptor->hdr[0].name, 0,
- sizeof(pHeaderDescriptor->hdr[0].name));
-
- snprintf(index,sizeof(index), "%d", ipa_if_num);
- strlcpy(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name));
- if (strlcat(pHeaderDescriptor->hdr[0].name, IPA_WAN_PARTIAL_HDR_NAME_v6, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX)
- {
- IPACMERR(" header name construction failed exceed length (%d)\n", strlen(pHeaderDescriptor->hdr[0].name));
- res = IPACM_FAILURE;
- goto fail;
- }
- pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len;
- pHeaderDescriptor->hdr[0].hdr_hdl = -1;
- pHeaderDescriptor->hdr[0].is_partial = 0;
- pHeaderDescriptor->hdr[0].status = -1;
-
- if (m_header.AddHeader(pHeaderDescriptor) == false ||
- pHeaderDescriptor->hdr[0].status != 0)
- {
- IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status);
- res = IPACM_FAILURE;
- goto fail;
- }
- else
- {
- header_set_v6 = true;
- hdr_hdl_sta_v6 = pHeaderDescriptor->hdr[0].hdr_hdl;
- IPACMDBG_H("add full header name: %s (%x)\n", pHeaderDescriptor->hdr[0].name, pHeaderDescriptor->hdr[0].hdr_hdl);
- }
- /* copy ipv6 full header to each TX endpoint property*/
- for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
- {
- if(tx_prop->tx[tx_index].ip==IPA_IP_v6)
- {
- memcpy(tx_prop->tx[tx_index].hdr_name, pHeaderDescriptor->hdr[0].name,
- sizeof(tx_prop->tx[tx_index].hdr_name));
- IPACMDBG_H("replace full header name: %s (%x) in tx:%d\n", tx_prop->tx[tx_index].hdr_name, pHeaderDescriptor->hdr[0].hdr_hdl,tx_index);
- }
- }
- break;
- }
+ if(get_client_memptr(wan_client, index)->ipv6_header_set)
+ {
+ hdr_hdl_sta_v6 = get_client_memptr(wan_client, index)->hdr_hdl_v6;
+ header_set_v6 = true;
+ IPACMDBG_H("add full ipv6 header hdl: (%x)\n", get_client_memptr(wan_client, index)->hdr_hdl_v6);
+ }
+ else
+ {
+ IPACMERR(" wan-client got ipv6 however didn't construct complete ipv6 header \n");
+ return IPACM_FAILURE;
+ }
+ }
+ else
+ {
+ IPACMDBG_H(" currently can't find matched wan-client's MAC-addr, waiting for header construction\n");
+ return IPACM_SUCCESS;
+ }
}
- /* see if default routes are setup before constructing full header */
- if(header_partial_default_wan_v4 == true)
+ /* see if default routes are setup before constructing full header */
+ if(header_partial_default_wan_v4 == true)
{
handle_route_add_evt(IPA_IP_v4);
}
- if(header_partial_default_wan_v6 == true)
+ if(header_partial_default_wan_v6 == true)
{
handle_route_add_evt(IPA_IP_v6);
}
-
-fail:
- free(pHeaderDescriptor);
-
return res;
}
@@ -1667,6 +1572,7 @@
}
else
{
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
ipv6_frag_firewall_flt_rule_hdl = m_pFilteringTable->rules[0].flt_rule_hdl;
IPACMDBG_H("Installed IPv6 frag firewall rule, handle %d.\n", ipv6_frag_firewall_flt_rule_hdl);
}
@@ -1697,25 +1603,39 @@
flt_rule_entry.status = -1;
/* firewall disable, all traffic are allowed */
- if(firewall_config.firewall_enable == true)
+ if(firewall_config.firewall_enable == true)
{
- flt_rule_entry.at_rear = true;
+ flt_rule_entry.at_rear = true;
- /* default action for v4 is go DST_NAT unless user set to exception*/
- if(firewall_config.rule_action_accept == true)
- {
- flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
- }
- else
- {
- flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT;
- }
- }
+ /* default action for v4 is go DST_NAT unless user set to exception*/
+ if(firewall_config.rule_action_accept == true)
+ {
+ flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
+ }
+ else
+ {
+ if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode == ROUTER)
+ {
+ flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT;
+ }
+ else
+ {
+ flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
+ }
+ }
+ }
else
{
- flt_rule_entry.at_rear = true;
- flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT;
- }
+ flt_rule_entry.at_rear = true;
+ if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode == ROUTER)
+ {
+ flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT;
+ }
+ else
+ {
+ flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
+ }
+ }
flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.hdl;
memcpy(&flt_rule_entry.rule.attrib,
@@ -1735,6 +1655,7 @@
}
else
{
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1);
IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status);
}
@@ -1776,14 +1697,21 @@
flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.hdl;
/* Accept v4 matched rules*/
- if(firewall_config.rule_action_accept == true)
- {
- flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT;
- }
- else
- {
- flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
- }
+ if(firewall_config.rule_action_accept == true)
+ {
+ if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode == ROUTER)
+ {
+ flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT;
+ }
+ else
+ {
+ flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
+ }
+ }
+ else
+ {
+ flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
+ }
memcpy(&flt_rule_entry.rule.attrib,
&firewall_config.extd_firewall_entries[i].attrib,
@@ -1812,6 +1740,7 @@
}
else
{
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1);
/* save v4 firewall filter rule handler */
IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n",
m_pFilteringTable->rules[rule_v4].flt_rule_hdl,
@@ -1835,6 +1764,7 @@
}
else
{
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1);
/* save v4 firewall filter rule handler */
IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n",
m_pFilteringTable->rules[rule_v4].flt_rule_hdl,
@@ -1858,6 +1788,7 @@
}
else
{
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1);
/* save v4 firewall filter rule handler */
IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n",
m_pFilteringTable->rules[rule_v4].flt_rule_hdl,
@@ -1877,7 +1808,7 @@
flt_rule_entry.status = -1;
/* firewall disable, all traffic are allowed */
- if(firewall_config.firewall_enable == true)
+ if(firewall_config.firewall_enable == true)
{
flt_rule_entry.at_rear = true;
@@ -1888,14 +1819,28 @@
}
else
{
- flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT;
- }
- }
+ if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode == ROUTER)
+ {
+ flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT;
+ }
+ else
+ {
+ flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
+ }
+ }
+ }
else
{
flt_rule_entry.at_rear = true;
- flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT;
- }
+ if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode == ROUTER)
+ {
+ flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT;
+ }
+ else
+ {
+ flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
+ }
+ }
flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.hdl;
memcpy(&flt_rule_entry.rule.attrib,
@@ -1917,6 +1862,7 @@
}
else
{
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1);
IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status);
}
@@ -1960,6 +1906,7 @@
}
else
{
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status);
}
/* copy filter hdls */
@@ -2024,6 +1971,7 @@
}
else
{
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status);
}
@@ -2092,6 +2040,7 @@
}
else
{
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
/* save v4 firewall filter rule handler */
IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status);
firewall_hdl_v6[rule_v6] = m_pFilteringTable->rules[0].flt_rule_hdl;
@@ -2110,6 +2059,7 @@
}
else
{
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
/* save v6 firewall filter rule handler */
IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status);
firewall_hdl_v6[rule_v6] = m_pFilteringTable->rules[0].flt_rule_hdl;
@@ -2119,7 +2069,6 @@
}
else
{
-
memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
if (false == m_filtering.AddFilteringRule(m_pFilteringTable))
{
@@ -2129,6 +2078,7 @@
}
else
{
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
/* save v6 firewall filter rule handler */
IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status);
firewall_hdl_v6[rule_v6] = m_pFilteringTable->rules[0].flt_rule_hdl;
@@ -2163,6 +2113,7 @@
}
else
{
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status);
}
/* copy filter hdls */
@@ -2220,6 +2171,7 @@
}
else
{
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status);
}
/* copy filter hdls*/
@@ -2785,7 +2737,7 @@
if(iptype == IPA_IP_v4)
{
- if(modem_ipv4_pdn_index == 0) //install ipv4 default modem DL filtering rules only once
+ if(modem_ipv4_pdn_index == 0) /* install ipv4 default modem DL filtering rules only once */
{
/* reset the num_v4_flt_rule*/
IPACM_Wan::num_v4_flt_rule = 0;
@@ -2794,7 +2746,7 @@
}
else if(iptype == IPA_IP_v6)
{
- if(modem_ipv6_pdn_index == 0) //install ipv6 default modem DL filtering rules only once
+ if(modem_ipv6_pdn_index == 0) /* install ipv6 default modem DL filtering rules only once */
{
/* reset the num_v6_flt_rule*/
IPACM_Wan::num_v6_flt_rule = 0;
@@ -3384,6 +3336,7 @@
IPACMERR("Error Deleting Filtering rules, aborting...\n");
return IPACM_FAILURE;
}
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, num_firewall_v4);
}
else
{
@@ -3396,6 +3349,7 @@
IPACMERR("Error Deleting Filtering rules, aborting...\n");
return IPACM_FAILURE;
}
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1);
num_firewall_v4 = 0;
}
@@ -3416,6 +3370,7 @@
IPACMERR("Error Deleting Filtering rules, aborting...\n");
return IPACM_FAILURE;
}
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, num_firewall_v6);
}
else
{
@@ -3428,16 +3383,19 @@
IPACMERR("Error Deleting Filtering rules, aborting...\n");
return IPACM_FAILURE;
}
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
if (m_filtering.DeleteFilteringHdls(&dft_wan_fl_hdl[2],
IPA_IP_v6, 1) == false)
{
IPACMERR("Error Deleting Filtering rules, aborting...\n");
return IPACM_FAILURE;
}
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
if (m_filtering.DeleteFilteringHdls(&ipv6_frag_firewall_flt_rule_hdl, IPA_IP_v6, 1) == false)
{
IPACMERR("Error deleting IPv6 frag filtering rules.\n");
}
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
num_firewall_v6 = 0;
}
@@ -3450,7 +3408,7 @@
uint32_t tx_index;
ipacm_cmd_q_data evt_data;
- IPACMDBG_H("got handle_route_del_evt with ip-family:%d \n", iptype);
+ IPACMDBG_H("got handle_route_del_evt for STA-mode with ip-family:%d \n", iptype);
if(tx_prop == NULL)
{
@@ -3928,6 +3886,7 @@
res = IPACM_FAILURE;
goto fail;
}
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPV4_DEFAULT_FILTERTING_RULES);
IPACMDBG_H("finished delete default v4 filtering rules\n ");
}
@@ -3943,6 +3902,7 @@
res = IPACM_FAILURE;
goto fail;
}
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, IPV6_DEFAULT_FILTERTING_RULES);
if(num_ipv6_dest_flt_rule > 0 && num_ipv6_dest_flt_rule <= MAX_DEFAULT_v6_ROUTE_RULES)
{
@@ -3952,28 +3912,11 @@
res = IPACM_FAILURE;
goto fail;
}
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, num_ipv6_dest_flt_rule);
}
IPACMDBG_H("finished delete default v6 filtering rules\n ");
}
- /* delete the complete header for STA mode*/
- if((header_set_v4 == true) || (header_set_v6 == true))
- {
- if (m_header.DeleteHeaderHdl(hdr_hdl_sta_v4) == false)
- {
- IPACMERR("ErrorDeleting STA header for v4, aborting...\n");
- res = IPACM_FAILURE;
- goto fail;
- }
-
- if (m_header.DeleteHeaderHdl(hdr_hdl_sta_v6) == false)
- {
- IPACMERR("ErrorDeleting STA header for v6, aborting...\n");
- res = IPACM_FAILURE;
- goto fail;
- }
- }
-
fail:
if (tx_prop != NULL)
{
@@ -4159,24 +4102,6 @@
handle_software_routing_disable();
}
- /* delete the complete header for STA mode*/
- if((header_set_v4 == true) || (header_set_v6 == true))
- {
- if (m_header.DeleteHeaderHdl(hdr_hdl_sta_v4) == false)
- {
- IPACMERR("ErrorDeleting STA header for v4, aborting...\n");
- res = IPACM_FAILURE;
- goto fail;
- }
-
- if (m_header.DeleteHeaderHdl(hdr_hdl_sta_v6) == false)
- {
- IPACMERR("ErrorDeleting STA header for v6, aborting...\n");
- res = IPACM_FAILURE;
- goto fail;
- }
- }
-
fail:
if (tx_prop != NULL)
{
diff --git a/ipacm/src/IPACM_Wlan.cpp b/ipacm/src/IPACM_Wlan.cpp
index 862836c..27e27f6 100644
--- a/ipacm/src/IPACM_Wlan.cpp
+++ b/ipacm/src/IPACM_Wlan.cpp
@@ -110,6 +110,23 @@
return;
}
+#ifdef FEATURE_ETH_BRIDGE_LE
+ exp_index_v4 = 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;
+ exp_index_v6 = 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
+ exp_index_v4 = 2*(IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
+ exp_index_v6 = 2*(IPV6_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR) + NUM_IPV6_PREFIX_FLT_RULE + NUM_IPV6_ICMP_FLT_RULE;
+#else
+ exp_index_v4 = 2*(IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
+ exp_index_v6 = 2*(IPV6_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR) + NUM_IPV6_PREFIX_FLT_RULE + NUM_IPV6_ICMP_FLT_RULE;
+#endif
+#ifdef FEATURE_IPA_ANDROID
+ exp_index_v4 = exp_index_v4 + 2 * (IPA_MAX_PRIVATE_SUBNET_ENTRIES - IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
+#endif
+#endif
IPACM_Wlan::num_wlan_ap_iface++;
IPACMDBG_H("Now the number of wlan AP iface is %d\n", IPACM_Wlan::num_wlan_ap_iface);
@@ -737,10 +754,13 @@
{
handle_SCC_MCC_switch(IPA_IP_v4);
handle_SCC_MCC_switch(IPA_IP_v6);
+ eth_bridge_handle_wlan_SCC_MCC_switch(IPA_IP_v4);
+ eth_bridge_handle_wlan_SCC_MCC_switch(IPA_IP_v6);
}
else
{
handle_SCC_MCC_switch(ip_type);
+ eth_bridge_handle_wlan_SCC_MCC_switch(ip_type);
}
break;
@@ -750,13 +770,37 @@
{
handle_SCC_MCC_switch(IPA_IP_v4);
handle_SCC_MCC_switch(IPA_IP_v6);
+ eth_bridge_handle_wlan_SCC_MCC_switch(IPA_IP_v4);
+ eth_bridge_handle_wlan_SCC_MCC_switch(IPA_IP_v6);
}
else
{
handle_SCC_MCC_switch(ip_type);
+ eth_bridge_handle_wlan_SCC_MCC_switch(ip_type);
}
break;
+ case IPA_CRADLE_WAN_MODE_SWITCH:
+ {
+ IPACMDBG_H("Received IPA_CRADLE_WAN_MODE_SWITCH event.\n");
+ ipacm_event_cradle_wan_mode* wan_mode = (ipacm_event_cradle_wan_mode*)param;
+ if(wan_mode == NULL)
+ {
+ IPACMERR("Event data is empty.\n");
+ return;
+ }
+
+ if(wan_mode->cradle_wan_mode == BRIDGE)
+ {
+ handle_cradle_wan_mode_switch(true);
+ }
+ else
+ {
+ handle_cradle_wan_mode_switch(false);
+ }
+ }
+ break;
+
default:
break;
}
@@ -1207,7 +1251,7 @@
int IPACM_Wlan::handle_uplink_filter_rule(ipacm_ext_prop* prop, ipa_ip_type iptype)
{
ipa_flt_rule_add flt_rule_entry;
- int len = 0, cnt, ret = IPACM_SUCCESS, offset;
+ int len = 0, cnt, ret = IPACM_SUCCESS, index;
ipa_ioc_add_flt_rule *pFilteringTable;
ipa_fltr_installed_notif_req_msg_v01 flt_index;
int fd;
@@ -1237,6 +1281,13 @@
if (0 == fd)
{
IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
+ return IPACM_FAILURE;
+ }
+ if (prop->num_ext_props > MAX_WAN_UL_FILTER_RULES)
+ {
+ IPACMERR("number of modem UL rules > MAX_WAN_UL_FILTER_RULES, aborting...\n");
+ close(fd);
+ return IPACM_FAILURE;
}
memset(&flt_index, 0, sizeof(flt_index));
@@ -1288,35 +1339,20 @@
goto fail;
}
- if(iptype == IPA_IP_v4)
+ index = IPACM_Iface::ipacmcfg->getFltRuleCount(rx_prop->rx[0].src_pipe, iptype);
+
+#ifndef FEATURE_IPA_ANDROID
+ if(iptype == IPA_IP_v4 && index != exp_index_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
+ IPACMDBG_DMESG("### WARNING ### num flt rules for IPv4 on client %d is not expected: %d expected value: %d",
+ rx_prop->rx[0].src_pipe, index, exp_index_v4);
}
- else
+ if(iptype == IPA_IP_v6 && index != exp_index_v6)
{
-#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
+ IPACMDBG_DMESG("### WARNING ### num flt rules for IPv6 on client %d is not expected: %d expected value: %d",
+ rx_prop->rx[0].src_pipe, index, exp_index_v6);
}
+#endif
for(cnt=0; cnt<prop->num_ext_props; cnt++)
{
@@ -1326,8 +1362,9 @@
flt_rule_entry.rule.rt_tbl_idx = prop->prop[cnt].rt_tbl_idx;
memcpy(&pFilteringTable->rules[cnt], &flt_rule_entry, sizeof(flt_rule_entry));
- flt_index.filter_index_list[cnt].filter_index = offset+cnt;
- IPACMDBG_H("Modem UL filtering rule %d has index %d\n", cnt, offset+cnt);
+ IPACMDBG_H("Modem UL filtering rule %d has index %d\n", cnt, index);
+ flt_index.filter_index_list[cnt].filter_index = index;
+ index++;
flt_index.filter_index_list[cnt].filter_handle = prop->prop[cnt].filter_hdl;
}
@@ -1354,6 +1391,7 @@
wan_ul_fl_rule_hdl_v4[num_wan_ul_fl_rule_v4] = pFilteringTable->rules[i].flt_rule_hdl;
num_wan_ul_fl_rule_v4++;
}
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, iptype, pFilteringTable->num_rules);
}
else if(iptype == IPA_IP_v6)
{
@@ -1362,6 +1400,7 @@
wan_ul_fl_rule_hdl_v6[num_wan_ul_fl_rule_v6] = pFilteringTable->rules[i].flt_rule_hdl;
num_wan_ul_fl_rule_v6++;
}
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, iptype, pFilteringTable->num_rules);
}
else
{
@@ -2206,17 +2245,6 @@
}
IPACMDBG_H("Deleted guest ap v4 filter rules successfully.\n");
#endif
-
- /* delete icmp filter rules */
- if(wlan_ap_index == 0)
- {
- 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
IPACMDBG_H("Delete tcp control flt rules.\n");
@@ -2275,6 +2303,17 @@
/* Delete v6 filtering rules */
if (ip_type != IPA_IP_v4 && rx_prop != NULL)
{
+ /* delete icmp filter rules */
+ if(wlan_ap_index == 0)
+ {
+ 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;
+ }
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, NUM_IPV6_ICMP_FLT_RULE);
+ }
IPACMDBG_H("Delete default %d v6 filter rules\n", IPV6_DEFAULT_FILTERTING_RULES);
/* delete default filter rules */
#ifdef FEATURE_ETH_BRIDGE_LE
@@ -3026,6 +3065,7 @@
}
else
{
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, iptype, num_rule);
/* copy filter rule hdls */
for (int i = 0; i < num_rule; i++)
{
@@ -3076,6 +3116,7 @@
}
else
{
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, iptype, num_rule);
/* copy filter rule hdls */
for (int i = 0; i < num_rule; i++)
{
@@ -3137,11 +3178,13 @@
IPACMERR("Failed to delete ipv4 dummy flt rules.\n");
return;
}
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, num_v4_dummy_rule);
if(m_filtering.DeleteFilteringHdls(IPACM_Wlan::dummy_flt_rule_hdl_v6, IPA_IP_v6, num_v6_dummy_rule) == false)
{
IPACMERR("Failed to delete ipv6 dummy flt rules.\n");
return;
}
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, num_v6_dummy_rule);
free(IPACM_Wlan::dummy_flt_rule_hdl_v4);
IPACM_Wlan::dummy_flt_rule_hdl_v4 = NULL;
@@ -4288,8 +4331,18 @@
res = IPACM_FAILURE;
goto fail;
}
+ /* Handle MCC Mode case */
+ if (IPACM_Iface::ipacmcfg->isMCC_Mode == true)
+ {
+ IPACMDBG_H("In MCC mode, use alt dst pipe: %d\n",
+ tx_prop->tx[i].alt_dst_pipe);
+ rt_rule.rule.dst = tx_prop->tx[i].alt_dst_pipe;
+ }
+ else
+ {
+ rt_rule.rule.dst = tx_prop->tx[i].dst_pipe;
+ }
- 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
{
@@ -4826,3 +4879,257 @@
}
return;
}
+
+void IPACM_Wlan::eth_bridge_handle_wlan_SCC_MCC_switch(ipa_ip_type iptype)
+{
+
+ for (int i= 0; i < IPACM_Lan::num_wlan_client; i++)
+ {
+ if (IPACM_Lan::eth_bridge_wlan_client[i].ipa_if_num == ipa_if_num)
+ {
+ if (IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.valid == true)
+ {
+ if (eth_bridge_modify_wlan_rt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac, SRC_WLAN, iptype) == IPACM_FAILURE)
+ {
+ IPACMDBG_H("SCC/MCC switch is failed for iptype: %d src_iface: %d \n", iptype, SRC_WLAN);
+ return;
+ }
+ }
+ if (IPACM_Lan::usb_to_wlan_hdr_proc_ctx.valid == true)
+ {
+ if (eth_bridge_modify_wlan_rt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac, SRC_USB, iptype) == IPACM_FAILURE)
+ {
+ IPACMDBG_H("SCC/MCC switch is failed for iptype: %d src_iface: %d \n", iptype, SRC_USB);
+ return;
+ }
+ }
+ }
+ }
+
+ IPACMDBG_H("SCC/MCC switch is successful for iptype: %d\n", iptype);
+}
+
+int IPACM_Wlan::eth_bridge_modify_wlan_rt_rule(uint8_t* mac, eth_bridge_src_iface src_iface, ipa_ip_type iptype)
+{
+ struct ipa_ioc_mdfy_rt_rule *rt_rule = NULL;
+ struct ipa_rt_rule_mdfy *rt_rule_entry;
+ uint32_t index = 0, num_rt_rule = 0, position;
+
+ if (tx_prop == NULL)
+ {
+ IPACMDBG_H("No tx properties \n");
+ return IPACM_FAILURE;
+ }
+
+ 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]);
+
+ if (iptype == IPA_IP_v4)
+ {
+ num_rt_rule = each_client_rt_rule_count_v4;
+ }
+ else
+ {
+ num_rt_rule = each_client_rt_rule_count_v6;
+ }
+
+ if (src_iface == SRC_WLAN)
+ {
+ if (iptype == IPA_IP_v4)
+ {
+ for (index = 0; index < wlan_client_rt_from_wlan_info_count_v4; index++)
+ {
+ if (memcmp(eth_bridge_get_client_rt_info_ptr(index, src_iface, IPA_IP_v4)->mac, mac,
+ sizeof(eth_bridge_get_client_rt_info_ptr(index, src_iface, IPA_IP_v4)->mac)) == 0)
+ {
+ position = index;
+ IPACMDBG_H("The client is found at position %d.\n", position);
+ break;
+ }
+ }
+ if (index == wlan_client_rt_from_wlan_info_count_v4)
+ {
+ IPACMERR("The client is not found.\n");
+ return IPACM_FAILURE;
+ }
+ }
+ else
+ {
+ for (index =0 ; index < wlan_client_rt_from_wlan_info_count_v6; index++)
+ {
+ if (memcmp(eth_bridge_get_client_rt_info_ptr(index, src_iface, IPA_IP_v6)->mac, mac,
+ sizeof(eth_bridge_get_client_rt_info_ptr(index, src_iface, IPA_IP_v6)->mac)) == 0)
+ {
+ position = index;
+ IPACMDBG_H("The client is found at position %d.\n", position);
+ break;
+ }
+ }
+ if (index == wlan_client_rt_from_wlan_info_count_v6)
+ {
+ IPACMERR("The client is not found.\n");
+ return IPACM_FAILURE;
+ }
+ }
+ }
+ else
+ {
+ if (iptype == IPA_IP_v4)
+ {
+ for (index = 0; index < wlan_client_rt_from_usb_info_count_v4; index++)
+ {
+ if (memcmp(eth_bridge_get_client_rt_info_ptr(index, src_iface, IPA_IP_v4)->mac, mac,
+ sizeof(eth_bridge_get_client_rt_info_ptr(index, src_iface, IPA_IP_v4)->mac)) == 0)
+ {
+ position = index;
+ IPACMDBG_H("The client is found at position %d.\n", position);
+ break;
+ }
+ }
+ if (index == wlan_client_rt_from_usb_info_count_v4)
+ {
+ IPACMERR("The client is not found.\n");
+ return IPACM_FAILURE;
+ }
+ }
+ else
+ {
+ for (index = 0; index < wlan_client_rt_from_usb_info_count_v6; index++)
+ {
+ if (memcmp(eth_bridge_get_client_rt_info_ptr(index, src_iface, IPA_IP_v6)->mac, mac,
+ sizeof(eth_bridge_get_client_rt_info_ptr(index, src_iface, IPA_IP_v6)->mac)) == 0)
+ {
+ position = index;
+ IPACMDBG_H("The client is found at position %d.\n", position);
+ break;
+ }
+ }
+ if (index == wlan_client_rt_from_usb_info_count_v6)
+ {
+ IPACMERR("The client is not found.\n");
+ return IPACM_FAILURE;
+ }
+ }
+ }
+
+ rt_rule = (struct ipa_ioc_mdfy_rt_rule *)
+ calloc(1, sizeof(struct ipa_ioc_mdfy_rt_rule) +
+ (num_rt_rule) * sizeof(struct ipa_rt_rule_mdfy));
+
+ if (rt_rule == NULL)
+ {
+ IPACMERR("Unable to allocate memory for modify rt rule\n");
+ return IPACM_FAILURE;
+ }
+ IPACMDBG("Allocated memory for %d rules successfully\n", num_rt_rule);
+
+ rt_rule->commit = 1;
+ rt_rule->num_rules = 0;
+ rt_rule->ip = iptype;
+
+ for (index = 0; index < tx_prop->num_tx_props; index++)
+ {
+ if (tx_prop->tx[index].ip == iptype)
+ {
+ if (rt_rule->num_rules >= num_rt_rule)
+ {
+ IPACMERR("Number of routing rules exceeds limit.\n");
+ free(rt_rule);
+ return IPACM_FAILURE;
+ }
+
+ rt_rule_entry = &rt_rule->rules[rt_rule->num_rules];
+
+ if (IPACM_Iface::ipacmcfg->isMCC_Mode)
+ {
+ IPACMDBG_H("In MCC mode, use alt dst pipe: %d\n",
+ tx_prop->tx[index].alt_dst_pipe);
+ rt_rule_entry->rule.dst = tx_prop->tx[index].alt_dst_pipe;
+ }
+ else
+ {
+ rt_rule_entry->rule.dst = tx_prop->tx[index].dst_pipe;
+ }
+
+ rt_rule_entry->rule.hdr_hdl = 0;
+
+ if (src_iface == SRC_WLAN)
+ {
+ rt_rule_entry->rule.hdr_proc_ctx_hdl =
+ IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.proc_ctx_hdl;
+ }
+ else
+ {
+ rt_rule_entry->rule.hdr_proc_ctx_hdl =
+ IPACM_Lan::usb_to_wlan_hdr_proc_ctx.proc_ctx_hdl;
+ }
+
+ memcpy(&rt_rule_entry->rule.attrib,
+ &tx_prop->tx[index].attrib,
+ sizeof(rt_rule_entry->rule.attrib));
+
+ if (src_iface == SRC_WLAN) //src is WLAN means packet is from WLAN
+ {
+ if (IPACM_Lan::wlan_hdr_type == IPA_HDR_L2_ETHERNET_II)
+ {
+ rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II;
+ }
+ else
+ {
+ rt_rule_entry->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_entry->rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II;
+ }
+ else
+ {
+ rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3;
+ }
+ }
+ memcpy(rt_rule_entry->rule.attrib.dst_mac_addr, mac,
+ sizeof(rt_rule_entry->rule.attrib.dst_mac_addr));
+ memset(rt_rule_entry->rule.attrib.dst_mac_addr_mask, 0xFF,
+ sizeof(rt_rule_entry->rule.attrib.dst_mac_addr_mask));
+
+ rt_rule_entry->rt_rule_hdl =
+ eth_bridge_get_client_rt_info_ptr(position, src_iface, iptype)->rt_rule_hdl[rt_rule->num_rules];
+ IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", index,
+ eth_bridge_get_client_rt_info_ptr(position, src_iface, iptype)->rt_rule_hdl[rt_rule->num_rules], iptype);
+
+ rt_rule->num_rules++;
+ }
+ }
+
+ if (rt_rule->num_rules > 0)
+ {
+ if (false == m_routing.ModifyRoutingRule(rt_rule))
+ {
+ IPACMERR("Routing rule modify failed!\n");
+ free(rt_rule);
+ return IPACM_FAILURE;
+ }
+ if (false == m_routing.Commit(iptype))
+ {
+ IPACMERR("Routing rule modify commit failed!\n");
+ free(rt_rule);
+ return IPACM_FAILURE;
+ }
+ IPACMDBG("Routing rule modified successfully \n");
+ }
+
+ if (rt_rule)
+ {
+ free(rt_rule);
+ }
+ return IPACM_SUCCESS;
+}
diff --git a/ipacm/src/IPACM_Xml.cpp b/ipacm/src/IPACM_Xml.cpp
index cf048db..03af08c 100644
--- a/ipacm/src/IPACM_Xml.cpp
+++ b/ipacm/src/IPACM_Xml.cpp
@@ -314,6 +314,26 @@
}
}
}
+ else if (IPACM_util_icmp_string((char*)xml_node->name, MODE_TAG) == 0)
+ {
+ content = IPACM_read_content_element(xml_node);
+ if (content)
+ {
+ str_size = strlen(content);
+ memset(content_buf, 0, sizeof(content_buf));
+ memcpy(content_buf, (void *)content, str_size);
+ if (0 == strncasecmp(content_buf, IFACE_ROUTER_MODE_TAG, str_size))
+ {
+ config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_mode = ROUTER;
+ IPACMDBG_H("Iface mode %d\n", config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_mode);
+ }
+ else if (0 == strncasecmp(content_buf, IFACE_BRIDGE_MODE_TAG, str_size))
+ {
+ config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_mode = BRIDGE;
+ IPACMDBG_H("Iface mode %d\n", config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_mode);
+ }
+ }
+ }
else if (IPACM_util_icmp_string((char*)xml_node->name,
SUBNETADDRESS_TAG) == 0)
{
diff --git a/ipacm/src/IPACM_cfg.xml b/ipacm/src/IPACM_cfg.xml
index 33a9166..6b3d6b9 100644
--- a/ipacm/src/IPACM_cfg.xml
+++ b/ipacm/src/IPACM_cfg.xml
@@ -13,6 +13,7 @@
<Iface>
<Name>ecm0</Name>
<Category>LAN</Category>
+ <Mode>ROUTER</Mode>
</Iface>
<Iface>
<Name>rmnet_data0</Name>
@@ -145,4 +146,4 @@
<MaxNatEntries>500</MaxNatEntries>
</IPACMNAT>
</IPACM>
-</system>
\ No newline at end of file
+</system>
diff --git a/ipanat/src/Android.mk b/ipanat/src/Android.mk
index a1116df..a97b6ce 100644
--- a/ipanat/src/Android.mk
+++ b/ipanat/src/Android.mk
@@ -15,7 +15,7 @@
LOCAL_CFLAGS := -DDEBUG
LOCAL_MODULE := libipanat
-LOCAL_MODULE_TAGS := debug
+LOCAL_MODULE_TAGS := optional
LOCAL_PRELINK_MODULE := false
include $(BUILD_SHARED_LIBRARY)