Merge d3eecdea17a9d9f8d5f75476f86a2b3f3cad99c2 on remote branch
Change-Id: I03e130262b22c7a20be9a1c52077cb8bb10969aa
diff --git a/ipacm/inc/IPACM_Config.h b/ipacm/inc/IPACM_Config.h
index 8d054a0..5bcb4eb 100644
--- a/ipacm/inc/IPACM_Config.h
+++ b/ipacm/inc/IPACM_Config.h
@@ -115,6 +115,8 @@
bool ipacm_odu_embms_enable;
+ bool ipacm_ip_passthrough_mode;
+
int ipa_nat_iface_entries;
/* Store the total number of wlan guest ap configured */
diff --git a/ipacm/inc/IPACM_Defs.h b/ipacm/inc/IPACM_Defs.h
index a6e76d1..b613392 100644
--- a/ipacm/inc/IPACM_Defs.h
+++ b/ipacm/inc/IPACM_Defs.h
@@ -75,7 +75,7 @@
#define IPA_ODU_HDR_NAME_v6 "IPACM_ODU_v6"
-#define IPA_MAX_IFACE_ENTRIES 15
+#define IPA_MAX_IFACE_ENTRIES 20
#define IPA_MAX_PRIVATE_SUBNET_ENTRIES 3
#define IPA_MAX_ALG_ENTRIES 20
#define IPA_MAX_RM_ENTRY 6
@@ -281,6 +281,10 @@
int if_index;
int if_index_tether;
enum ipa_ip_type iptype;
+#ifdef IPA_WAN_MSG_IPv6_ADDR_GW_LEN
+ uint32_t ipv4_addr_gw;
+ uint32_t ipv6_addr_gw[4];
+#endif
} ipacm_event_data_iptype;
diff --git a/ipacm/inc/IPACM_Iface.h b/ipacm/inc/IPACM_Iface.h
index 89bb26f..43b0da6 100644
--- a/ipacm/inc/IPACM_Iface.h
+++ b/ipacm/inc/IPACM_Iface.h
@@ -129,6 +129,9 @@
/*Configure the initial filter rules */
virtual int init_fl_rule(ipa_ip_type iptype);
+ /* Change IP Type.*/
+ void config_ip_type(ipa_ip_type iptype);
+
/* Get interface index */
virtual int ipa_get_if_index(char * if_name, int * if_index);
diff --git a/ipacm/inc/IPACM_Lan.h b/ipacm/inc/IPACM_Lan.h
index 0076a01..6c54f5e 100644
--- a/ipacm/inc/IPACM_Lan.h
+++ b/ipacm/inc/IPACM_Lan.h
@@ -222,6 +222,8 @@
uint32_t if_ipv4_subnet;
+ uint32_t ipv6_prefix[2];
+
private:
/* get hdr proc ctx type given source and destination l2 hdr type */
diff --git a/ipacm/inc/IPACM_Routing.h b/ipacm/inc/IPACM_Routing.h
index 4f5488f..b5ffabc 100644
--- a/ipacm/inc/IPACM_Routing.h
+++ b/ipacm/inc/IPACM_Routing.h
@@ -61,7 +61,6 @@
bool Reset(enum ipa_ip_type ip);
bool GetRoutingTable(struct ipa_ioc_get_rt_tbl *routingTable);
- bool PutRoutingTable(uint32_t routingTableHandle);
bool DeviceNodeIsOpened();
bool DeleteRoutingHdl(uint32_t rt_rule_hdl, ipa_ip_type ip);
@@ -71,6 +70,8 @@
private:
static const char *DEVICE_NAME;
int m_fd; /* File descriptor of the IPA device node /dev/ipa */
+
+ bool PutRoutingTable(uint32_t routingTableHandle);
};
#endif //IPACM_ROUTING_H
diff --git a/ipacm/inc/IPACM_Wan.h b/ipacm/inc/IPACM_Wan.h
index b4bf50e..fe6d35e 100644
--- a/ipacm/inc/IPACM_Wan.h
+++ b/ipacm/inc/IPACM_Wan.h
@@ -97,6 +97,7 @@
static uint8_t xlat_mux_id;
/* IPACM interface name */
static char wan_up_dev_name[IF_NAME_LEN];
+ static uint32_t curr_wan_ip;
IPACM_Wan(int, ipacm_wan_iface_type, uint8_t *);
virtual ~IPACM_Wan();
@@ -140,6 +141,11 @@
#endif
}
+ static uint32_t getWANIP()
+ {
+ return curr_wan_ip;
+ }
+
static bool getXlat_Mux_Id()
{
return xlat_mux_id;
@@ -176,6 +182,7 @@
private:
+ bool is_ipv6_frag_firewall_flt_rule_installed;
uint32_t ipv6_frag_firewall_flt_rule_hdl;
uint32_t *wan_route_rule_v4_hdl;
uint32_t *wan_route_rule_v6_hdl;
@@ -452,9 +459,6 @@
int config_dft_firewall_rules_ex(struct ipa_flt_rule_add* rules, int rule_offset,
ipa_ip_type iptype);
- /* Change IP Type.*/
- void config_ip_type(ipa_ip_type iptype);
-
/* init filtering rule in wan dl filtering table */
int init_fl_rule_ex(ipa_ip_type iptype);
diff --git a/ipacm/inc/IPACM_Xml.h b/ipacm/inc/IPACM_Xml.h
index f645ae1..64c00ed 100644
--- a/ipacm/inc/IPACM_Xml.h
+++ b/ipacm/inc/IPACM_Xml.h
@@ -178,6 +178,9 @@
#define IPACMNat_TAG "IPACMNAT"
#define NAT_MaxEntries_TAG "MaxNatEntries"
+#define IP_PassthroughFlag_TAG "IPPassthroughFlag"
+#define IP_PassthroughMode_TAG "IPPassthroughMode"
+
/*---------------------------------------------------------------------------
IP protocol numbers - use in dss_socket() to identify protocols.
Also contains the extension header types for IPv6.
@@ -276,6 +279,7 @@
bool router_mode_enable;
bool odu_embms_enable;
int num_wlan_guest_ap;
+ bool ip_passthrough_mode;
} IPACM_conf_t;
/* This function read IPACM XML configuration*/
diff --git a/ipacm/src/Android.mk b/ipacm/src/Android.mk
index c4a8b36..9a4d659 100644
--- a/ipacm/src/Android.mk
+++ b/ipacm/src/Android.mk
@@ -1,6 +1,5 @@
BOARD_PLATFORM_LIST := msm8916
BOARD_PLATFORM_LIST += msm8909
-BOARD_PLATFORM_LIST += msm8937
ifneq ($(call is-board-platform-in-list,$(BOARD_PLATFORM_LIST)),true)
ifneq (,$(filter $(QCOM_BOARD_PLATFORMS),$(TARGET_BOARD_PLATFORM)))
ifneq (, $(filter aarch64 arm arm64, $(TARGET_ARCH)))
diff --git a/ipacm/src/IPACM_Config.cpp b/ipacm/src/IPACM_Config.cpp
index 29ce787..d8c4227 100644
--- a/ipacm/src/IPACM_Config.cpp
+++ b/ipacm/src/IPACM_Config.cpp
@@ -287,6 +287,10 @@
IPACMDBG_H("ipacm_odu_enable %d\n", ipacm_odu_enable);
IPACMDBG_H("ipacm_odu_mode %d\n", ipacm_odu_router_mode);
IPACMDBG_H("ipacm_odu_embms_enable %d\n", ipacm_odu_embms_enable);
+
+ ipacm_ip_passthrough_mode = cfg->ip_passthrough_mode;
+ IPACMDBG_H("ipacm_ip_passthrough_mode %d. \n", ipacm_ip_passthrough_mode);
+
ipa_num_wlan_guest_ap = cfg->num_wlan_guest_ap;
IPACMDBG_H("ipa_num_wlan_guest_ap %d\n",ipa_num_wlan_guest_ap);
diff --git a/ipacm/src/IPACM_ConntrackListener.cpp b/ipacm/src/IPACM_ConntrackListener.cpp
index 33023cb..38ab7da 100644
--- a/ipacm/src/IPACM_ConntrackListener.cpp
+++ b/ipacm/src/IPACM_ConntrackListener.cpp
@@ -33,6 +33,8 @@
#include "IPACM_ConntrackListener.h"
#include "IPACM_ConntrackClient.h"
#include "IPACM_EvtDispatcher.h"
+#include "IPACM_Iface.h"
+#include "IPACM_Wan.h"
IPACM_ConntrackListener::IPACM_ConntrackListener()
{
@@ -210,30 +212,11 @@
pNatIfaces[i].iface_name,
sizeof(pNatIfaces[i].iface_name)) == 0)
{
- /* copy the ipv4 address to filter out downlink connections
- ignore downlink after listening connection event from
- conntrack as it is not destinated to private ip address */
- IPACMDBG("Interface (%s) is nat\n", ifr.ifr_name);
- for (j = 0; j < MAX_IFACE_ADDRESS; j++)
- {
- /* check if duplicate NAT ip */
- if (nat_iface_ipv4_addr[j] == data->ipv4_addr)
- {
- *NatIface = true;
- return IPACM_SUCCESS;
- }
-
- if (nat_iface_ipv4_addr[j] == 0)
- {
- nat_iface_ipv4_addr[j] = data->ipv4_addr;
- IPACMDBG_H("Nating connections of Interface (%s), entry (%d) ",
+ IPACMDBG_H("Nat iface (%s), entry (%d), dont cache",
pNatIfaces[i].iface_name, j);
- iptodot("with ipv4 address: ", nat_iface_ipv4_addr[j]);
-
- *NatIface = true;
- return IPACM_SUCCESS;
- }
- }
+ iptodot("with ipv4 address: ", nat_iface_ipv4_addr[j]);
+ *NatIface = true;
+ return IPACM_SUCCESS;
}
}
@@ -247,6 +230,12 @@
bool NatIface = false;
int cnt, ret;
+ if (isStaMode)
+ {
+ IPACMDBG("In STA mode, don't add dummy rules for non nat ifaces\n");
+ return;
+ }
+
/* Handle only non nat ifaces, NAT iface should be handle
separately to avoid race conditions between route/nat
rules add/delete operations */
@@ -261,6 +250,9 @@
if (nonnat_iface_ipv4_addr[cnt] == 0)
{
nonnat_iface_ipv4_addr[cnt] = data->ipv4_addr;
+ IPACMDBG("Add ip addr to non nat list (%d) ", cnt);
+ iptodot("with ipv4 address", nonnat_iface_ipv4_addr[cnt]);
+
/* Add dummy nat rule for non nat ifaces */
nat_inst->FlushTempEntries(data->ipv4_addr, true, true);
return;
@@ -700,6 +692,18 @@
int cnt;
*isTempEntry = false;
+
+ /* Special handling for Passthrough IP. */
+ if (IPACM_Iface::ipacmcfg->ipacm_ip_passthrough_mode)
+ {
+ if (rule->private_ip == IPACM_Wan::getWANIP())
+ {
+ IPACMDBG("In Passthrough mode and entry matched with Wan IP (0x%x)\n",
+ rule->private_ip);
+ return true;
+ }
+ }
+
/* check whether nat iface or not */
for (cnt = 0; cnt < MAX_IFACE_ADDRESS; cnt++)
{
@@ -716,27 +720,32 @@
}
}
- /* check whether non nat iface or not, on Nat iface
- add dummy rule by copying public ip to private ip */
- for (cnt = 0; cnt < MAX_IFACE_ADDRESS; cnt++)
+ if (!isStaMode)
{
- if (nonnat_iface_ipv4_addr[cnt] != 0)
+ /* check whether non nat iface or not, on Non Nat iface
+ add dummy rule by copying public ip to private ip */
+ for (cnt = 0; cnt < MAX_IFACE_ADDRESS; cnt++)
{
- if (rule->private_ip == nonnat_iface_ipv4_addr[cnt] ||
- rule->target_ip == nonnat_iface_ipv4_addr[cnt])
+ if (nonnat_iface_ipv4_addr[cnt] != 0)
{
- IPACMDBG("matched non_nat_iface_ipv4_addr entry(%d)\n", cnt);
- iptodot("AddIface(): Non Nat entry match with ip addr",
- nat_iface_ipv4_addr[cnt]);
+ if (rule->private_ip == nonnat_iface_ipv4_addr[cnt] ||
+ rule->target_ip == nonnat_iface_ipv4_addr[cnt])
+ {
+ IPACMDBG("matched non_nat_iface_ipv4_addr entry(%d)\n", cnt);
+ iptodot("AddIface(): Non Nat entry match with ip addr",
+ nonnat_iface_ipv4_addr[cnt]);
- rule->private_ip = rule->public_ip;
- rule->private_port = rule->public_port;
- return true;
+ rule->private_ip = rule->public_ip;
+ rule->private_port = rule->public_port;
+ return true;
+ }
}
}
+ IPACMDBG_H("Not mtaching with non-nat ifaces\n");
}
+ else
+ IPACMDBG("In STA mode, don't compare against non nat ifaces\n");
- IPACMDBG_H("Not mtaching with non-nat ifaces\n");
if(pConfig == NULL)
{
pConfig = IPACM_Config::GetInstance();
diff --git a/ipacm/src/IPACM_Conntrack_NATApp.cpp b/ipacm/src/IPACM_Conntrack_NATApp.cpp
index 93627bb..f0bdd99 100644
--- a/ipacm/src/IPACM_Conntrack_NATApp.cpp
+++ b/ipacm/src/IPACM_Conntrack_NATApp.cpp
@@ -242,7 +242,7 @@
cache[cnt].protocol == rule->protocol)
{
log_nat(rule->protocol,rule->private_ip,rule->target_ip,rule->private_port,\
- rule->target_port,"Duplicate Rule");
+ rule->target_port,"Duplicate Rule\n");
return true;
}
}
@@ -257,7 +257,7 @@
IPACMDBG("%s() %d\n", __FUNCTION__, __LINE__);
log_nat(rule->protocol,rule->private_ip,rule->target_ip,rule->private_port,\
- rule->target_port,"for deletion");
+ rule->target_port,"for deletion\n");
for(; cnt < max_entries; cnt++)
@@ -302,7 +302,7 @@
CHK_TBL_HDL();
log_nat(rule->protocol,rule->private_ip,rule->target_ip,rule->private_port,\
- rule->target_port,"for addition");
+ rule->target_port,"for addition\n");
if(isAlgPort(rule->protocol, rule->private_port) ||
isAlgPort(rule->protocol, rule->target_port))
{
diff --git a/ipacm/src/IPACM_Iface.cpp b/ipacm/src/IPACM_Iface.cpp
index 04cb162..84132c9 100644
--- a/ipacm/src/IPACM_Iface.cpp
+++ b/ipacm/src/IPACM_Iface.cpp
@@ -642,48 +642,6 @@
const char *dev_wlan1="wlan1";
const char *dev_ecm0="ecm0";
- /* update the iface ip-type to be IPA_IP_v4, IPA_IP_v6 or both*/
- if (iptype == IPA_IP_v4)
- {
-
- if ((ip_type == IPA_IP_v4) || (ip_type == IPA_IP_MAX))
- {
- IPACMDBG_H(" interface(%s:%d) already in ip-type %d\n", dev_name, ipa_if_num, ip_type);
- return res;
- }
-
- if (ip_type == IPA_IP_v6)
- {
- ip_type = IPA_IP_MAX;
- }
- else
- {
- ip_type = IPA_IP_v4;
- }
-
- IPACMDBG_H(" interface(%s:%d) now ip-type is %d\n", dev_name, ipa_if_num, ip_type);
- }
- else
- {
-
- if ((ip_type == IPA_IP_v6) || (ip_type == IPA_IP_MAX))
- {
- IPACMDBG_H(" interface(%s:%d) already in ip-type %d\n", dev_name, ipa_if_num, ip_type);
- return res;
- }
-
- if (ip_type == IPA_IP_v4)
- {
- ip_type = IPA_IP_MAX;
- }
- else
- {
- ip_type = IPA_IP_v6;
- }
-
- IPACMDBG_H(" interface(%s:%d) now ip-type is %d\n", dev_name, ipa_if_num, ip_type);
- }
-
/* ADD corresponding ipa_rm_resource_name of RX-endpoint before adding all IPV4V6 FT-rules */
if((IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat== WAN_IF) || (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat== EMBMS_IF))
{
@@ -991,3 +949,47 @@
close(fd);
return IPACM_SUCCESS;
}
+
+void IPACM_Iface::config_ip_type(ipa_ip_type iptype)
+{
+ /* update the iface ip-type to be IPA_IP_v4, IPA_IP_v6 or both*/
+ if (iptype == IPA_IP_v4)
+ {
+ if ((ip_type == IPA_IP_v4) || (ip_type == IPA_IP_MAX))
+ {
+ IPACMDBG_H(" interface(%s:%d) already in ip-type %d\n", dev_name, ipa_if_num, ip_type);
+ return;
+ }
+
+ if (ip_type == IPA_IP_v6)
+ {
+ ip_type = IPA_IP_MAX;
+ }
+ else
+ {
+ ip_type = IPA_IP_v4;
+ }
+ IPACMDBG_H(" interface(%s:%d) now ip-type is %d\n", dev_name, ipa_if_num, ip_type);
+ }
+ else
+ {
+ if ((ip_type == IPA_IP_v6) || (ip_type == IPA_IP_MAX))
+ {
+ IPACMDBG_H(" interface(%s:%d) already in ip-type %d\n", dev_name, ipa_if_num, ip_type);
+ return;
+ }
+
+ if (ip_type == IPA_IP_v4)
+ {
+ ip_type = IPA_IP_MAX;
+ }
+ else
+ {
+ ip_type = IPA_IP_v6;
+ }
+
+ IPACMDBG_H(" interface(%s:%d) now ip-type is %d\n", dev_name, ipa_if_num, ip_type);
+ }
+
+ return;
+}
diff --git a/ipacm/src/IPACM_IfaceManager.cpp b/ipacm/src/IPACM_IfaceManager.cpp
index ef5e0a0..a142553 100644
--- a/ipacm/src/IPACM_IfaceManager.cpp
+++ b/ipacm/src/IPACM_IfaceManager.cpp
@@ -56,8 +56,8 @@
IPACM_EvtDispatcher::registr(IPA_CFG_CHANGE_EVENT, this); // register for IPA_CFG_CHANGE event
IPACM_EvtDispatcher::registr(IPA_LINK_UP_EVENT, this);
IPACM_EvtDispatcher::registr(IPA_WLAN_AP_LINK_UP_EVENT, this); // register for wlan AP-iface
-#ifndef FEATURE_IPA_ANDROID
IPACM_EvtDispatcher::registr(IPA_WLAN_STA_LINK_UP_EVENT, this); // register for wlan STA-iface
+#ifndef FEATURE_IPA_ANDROID
/* only MDM targets support device on bridge mode */
IPACM_EvtDispatcher::registr(IPA_BRIDGE_LINK_UP_EVENT, this); // register for IPA_BRIDGE_LINK_UP_EVENT event
#endif /* not defined(FEATURE_IPA_ANDROID)*/
diff --git a/ipacm/src/IPACM_Lan.cpp b/ipacm/src/IPACM_Lan.cpp
index 6085aca..251814a 100644
--- a/ipacm/src/IPACM_Lan.cpp
+++ b/ipacm/src/IPACM_Lan.cpp
@@ -120,6 +120,7 @@
memset(ipv6_icmp_flt_rule_hdl, 0, NUM_IPV6_ICMP_FLT_RULE * sizeof(uint32_t));
modem_ul_v4_set = false;
modem_ul_v6_set = false;
+ memset(ipv6_prefix, 0, sizeof(ipv6_prefix));
/* ODU routing table initilization */
if(ipa_if_cate == ODU_IF)
@@ -379,6 +380,7 @@
{
if((data->iptype == IPA_IP_v6 || data->iptype == IPA_IP_MAX) && num_dft_rt_v6 == 1)
{
+ memcpy(ipv6_prefix, IPACM_Wan::backhaul_ipv6_prefix, sizeof(ipv6_prefix));
install_ipv6_prefix_flt_rule(IPACM_Wan::backhaul_ipv6_prefix);
if(IPACM_Wan::backhaul_is_sta_mode == false)
{
@@ -481,6 +483,7 @@
{
if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
{
+ memcpy(ipv6_prefix, data_wan_tether->ipv6_prefix, sizeof(ipv6_prefix));
install_ipv6_prefix_flt_rule(data_wan_tether->ipv6_prefix);
if(data_wan_tether->is_sta == false)
{
@@ -576,16 +579,17 @@
IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta);
if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
{
+ memcpy(ipv6_prefix, data_wan->ipv6_prefix, sizeof(ipv6_prefix));
install_ipv6_prefix_flt_rule(data_wan->ipv6_prefix);
- if(data_wan->is_sta == false)
- {
+ if(data_wan->is_sta == false)
+ {
ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
}
- else
- {
- handle_wan_up(IPA_IP_v6);
- }
+ else
+ {
+ handle_wan_up(IPA_IP_v6);
+ }
}
break;
@@ -779,7 +783,7 @@
{
uint32_t tx_index;
uint32_t rt_hdl;
- int num_v6, clnt_indx;
+ int num_v6 =0, clnt_indx;
clnt_indx = get_eth_client_index(data->mac_addr);
if (clnt_indx == IPACM_INVALID_INDEX)
@@ -948,6 +952,9 @@
}
#endif /* defined(FEATURE_IPA_ANDROID)*/
+ /* Update the IP Type. */
+ config_ip_type(data->iptype);
+
if (data->iptype == IPA_IP_v4)
{
rt_rule = (struct ipa_ioc_add_rt_rule *)
@@ -967,7 +974,7 @@
rt_rule_entry->at_rear = false;
rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS; //go to A5
rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
- strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name);
+ strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name, sizeof(rt_rule->rt_tbl_name));
rt_rule_entry->rule.attrib.u.v4.dst_addr = data->ipv4_addr;
rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
#ifdef FEATURE_IPA_V3
@@ -1024,7 +1031,7 @@
rt_rule->commit = 1;
rt_rule->num_rules = NUM_RULES;
rt_rule->ip = data->iptype;
- strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_v6.name);
+ strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_v6.name, sizeof(rt_rule->rt_tbl_name));
rt_rule_entry = &rt_rule->rules[0];
rt_rule_entry->at_rear = false;
@@ -1060,7 +1067,7 @@
dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6] = rt_rule_entry->rt_rule_hdl;
/* setup same rule for v6_wan table*/
- strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name);
+ strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, sizeof(rt_rule->rt_tbl_name));
if (false == m_routing.AddRoutingRule(rt_rule))
{
IPACMERR("Routing rule addition failed!\n");
@@ -1135,13 +1142,6 @@
m_pFilteringTable->ip = IPA_IP_v4;
m_pFilteringTable->num_rules = (uint8_t)IPACM_Iface::ipacmcfg->ipa_num_private_subnet;
- if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_lan_v4))
- {
- IPACMERR("LAN m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_lan_v4=0x%p) Failed.\n", &IPACM_Iface::ipacmcfg->rt_tbl_lan_v4);
- free(m_pFilteringTable);
- return IPACM_FAILURE;
- }
-
/* Make LAN-traffic always go A5, use default IPA-RT table */
if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_default_v4))
{
@@ -1685,6 +1685,8 @@
{
int clnt_indx;
int v6_num;
+ uint32_t ipv6_link_local_prefix = 0xFE800000;
+ uint32_t ipv6_link_local_prefix_mask = 0xFFC00000;
IPACMDBG_H("number of eth clients: %d\n", num_eth_client);
IPACMDBG_H("event MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
@@ -1731,10 +1733,10 @@
get_client_memptr(eth_client, clnt_indx)->route_rule_set_v4 = false;
get_client_memptr(eth_client, clnt_indx)->v4_addr = data->ipv4_addr;
}
+ }
}
- }
- else
- {
+ else
+ {
IPACMDBG_H("Invalid client IPv4 address \n");
return IPACM_FAILURE;
}
@@ -1744,21 +1746,28 @@
if ((data->ipv6_addr[0] != 0) || (data->ipv6_addr[1] != 0) ||
(data->ipv6_addr[2] != 0) || (data->ipv6_addr[3] || 0)) /* check if all 0 not valid ipv6 address */
{
- IPACMDBG_H("ipv6 address: 0x%x:%x:%x:%x\n", data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]);
- if(get_client_memptr(eth_client, clnt_indx)->ipv6_set < IPV6_NUM_ADDR)
- {
+ IPACMDBG_H("ipv6 address: 0x%x:%x:%x:%x\n", data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]);
+ if( (data->ipv6_addr[0] & ipv6_link_local_prefix_mask) != (ipv6_link_local_prefix & ipv6_link_local_prefix_mask) &&
+ memcmp(ipv6_prefix, data->ipv6_addr, sizeof(ipv6_prefix)) != 0)
+ {
+ IPACMDBG_H("This IPv6 address is not global IPv6 address with correct prefix, ignore.\n");
+ return IPACM_FAILURE;
+ }
+
+ if(get_client_memptr(eth_client, clnt_indx)->ipv6_set < IPV6_NUM_ADDR)
+ {
for(v6_num=0;v6_num < get_client_memptr(eth_client, clnt_indx)->ipv6_set;v6_num++)
- {
- if( data->ipv6_addr[0] == get_client_memptr(eth_client, clnt_indx)->v6_addr[v6_num][0] &&
+ {
+ if( data->ipv6_addr[0] == get_client_memptr(eth_client, clnt_indx)->v6_addr[v6_num][0] &&
data->ipv6_addr[1] == get_client_memptr(eth_client, clnt_indx)->v6_addr[v6_num][1] &&
data->ipv6_addr[2]== get_client_memptr(eth_client, clnt_indx)->v6_addr[v6_num][2] &&
data->ipv6_addr[3] == get_client_memptr(eth_client, clnt_indx)->v6_addr[v6_num][3])
- {
- IPACMDBG_H("Already see this ipv6 addr at position: %d for client:%d\n", v6_num, clnt_indx);
- return IPACM_FAILURE; /* not setup the RT rules*/
- }
- }
+ {
+ IPACMDBG_H("Already see this ipv6 addr at position: %d for client:%d\n", v6_num, clnt_indx);
+ return IPACM_FAILURE; /* not setup the RT rules*/
+ }
+ }
/* not see this ipv6 before for wifi client*/
get_client_memptr(eth_client, clnt_indx)->v6_addr[get_client_memptr(eth_client, clnt_indx)->ipv6_set][0] = data->ipv6_addr[0];
@@ -1769,8 +1778,8 @@
}
else
{
- IPACMDBG_H("Already got 3 ipv6 addr for client:%d\n", clnt_indx);
- return IPACM_FAILURE; /* not setup the RT rules*/
+ IPACMDBG_H("Already got %d ipv6 addr for client:%d\n", IPV6_NUM_ADDR, clnt_indx);
+ return IPACM_FAILURE; /* not setup the RT rules*/
}
}
}
@@ -2055,7 +2064,7 @@
memset(pHeaderDescriptor->hdr[0].name, 0,
sizeof(pHeaderDescriptor->hdr[0].name));
- strcpy(pHeaderDescriptor->hdr[0].name, IPA_ODU_HDR_NAME_v4);
+ strlcpy(pHeaderDescriptor->hdr[0].name, IPA_ODU_HDR_NAME_v4, sizeof(pHeaderDescriptor->hdr[0].name));
pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len;
pHeaderDescriptor->hdr[0].hdr_hdl = -1;
pHeaderDescriptor->hdr[0].is_partial = 0;
@@ -2135,7 +2144,7 @@
memset(pHeaderDescriptor->hdr[0].name, 0,
sizeof(pHeaderDescriptor->hdr[0].name));
- strcpy(pHeaderDescriptor->hdr[0].name, IPA_ODU_HDR_NAME_v6);
+ strlcpy(pHeaderDescriptor->hdr[0].name, IPA_ODU_HDR_NAME_v6, sizeof(pHeaderDescriptor->hdr[0].name));
pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len;
pHeaderDescriptor->hdr[0].hdr_hdl = -1;
pHeaderDescriptor->hdr[0].is_partial = 0;
@@ -2202,13 +2211,13 @@
if (IPA_IP_v4 == tx_prop->tx[tx_index].ip)
{
- strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_odu_v4.name);
+ strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_odu_v4.name, sizeof(rt_rule->rt_tbl_name));
rt_rule_entry->rule.hdr_hdl = ODU_hdr_hdl_v4;
rt_rule->ip = IPA_IP_v4;
}
else
{
- strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_odu_v6.name);
+ strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_odu_v6.name, sizeof(rt_rule->rt_tbl_name));
rt_rule_entry->rule.hdr_hdl = ODU_hdr_hdl_v6;
rt_rule->ip = IPA_IP_v6;
}
@@ -2931,6 +2940,8 @@
delete_ipv6_prefix_flt_rule();
+ memset(ipv6_prefix, 0, sizeof(ipv6_prefix));
+
if(is_sta_mode == false)
{
if (num_wan_ul_fl_rule_v6 > MAX_WAN_UL_FILTER_RULES)
@@ -3476,7 +3487,7 @@
flt_rule_entry.status = -1;
flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
#ifdef FEATURE_IPA_V3
- flt_rule_entry.rule.hashable = false;
+ flt_rule_entry.rule.hashable = true;
#endif
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;
@@ -3889,6 +3900,12 @@
uint32_t hdr_template;
ipa_ioc_add_hdr_proc_ctx* pHeaderProcTable = NULL;
+ if(tx_prop == NULL)
+ {
+ IPACMERR("No tx prop.\n");
+ return IPACM_FAILURE;
+ }
+
len = sizeof(struct ipa_ioc_add_hdr_proc_ctx) + sizeof(struct ipa_hdr_proc_ctx_add);
pHeaderProcTable = (ipa_ioc_add_hdr_proc_ctx*)malloc(len);
if(pHeaderProcTable == NULL)
@@ -4051,7 +4068,8 @@
{
if (tx_prop->tx[index].ip == iptype)
{
- if (rt_rule->num_rules >= rt_rule_count)
+ if (rt_rule->num_rules >= rt_rule_count ||
+ rt_rule->num_rules >= MAX_NUM_PROP)
{
IPACMERR("Number of routing rules exceeds limit.\n");
res = IPACM_FAILURE;
@@ -4152,6 +4170,7 @@
flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
flt_rule_entry.rule.eq_attrib_type = 0;
flt_rule_entry.rule.rt_tbl_hdl = rt_tbl_hdl;
+ flt_rule_entry.rule.hashable = true;
memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib));
if(tx_prop->tx[0].hdr_l2_type == IPA_HDR_L2_ETHERNET_II)
diff --git a/ipacm/src/IPACM_LanToLan.cpp b/ipacm/src/IPACM_LanToLan.cpp
index be33acd..bf47a82 100644
--- a/ipacm/src/IPACM_LanToLan.cpp
+++ b/ipacm/src/IPACM_LanToLan.cpp
@@ -593,7 +593,6 @@
m_p_iface->eth_bridge_add_flt_rule(client->mac_addr, rt_tbl.hdl,
iptype, &flt_rule_hdl);
IPACMDBG_H("Installed flt rule for IP type %d: handle %d\n", iptype, flt_rule_hdl);
- IPACM_Iface::m_routing.PutRoutingTable(rt_tbl.hdl);
for(it_flt = peer->flt_rule.begin(); it_flt != peer->flt_rule.end(); it_flt++)
{
@@ -889,6 +888,12 @@
{
uint32_t hdr_proc_ctx_hdl;
+ if(m_p_iface->tx_prop == NULL)
+ {
+ IPACMERR("No tx prop.\n");
+ return;
+ }
+
m_intra_interface_info.peer = this;
snprintf(m_intra_interface_info.rt_tbl_name_for_flt[IPA_IP_v4], IPA_RESOURCE_NAME_MAX,
diff --git a/ipacm/src/IPACM_Main.cpp b/ipacm/src/IPACM_Main.cpp
index fe13e67..c6ab9ee 100644
--- a/ipacm/src/IPACM_Main.cpp
+++ b/ipacm/src/IPACM_Main.cpp
@@ -533,6 +533,16 @@
ipa_get_if_index(event_wan.upstream_ifname, &(data_iptype->if_index));
ipa_get_if_index(event_wan.tethered_ifname, &(data_iptype->if_index_tether));
data_iptype->iptype = event_wan.ip;
+#ifdef IPA_WAN_MSG_IPv6_ADDR_GW_LEN
+ data_iptype->ipv4_addr_gw = event_wan.ipv4_addr_gw;
+ data_iptype->ipv6_addr_gw[0] = event_wan.ipv6_addr_gw[0];
+ data_iptype->ipv6_addr_gw[1] = event_wan.ipv6_addr_gw[1];
+ data_iptype->ipv6_addr_gw[2] = event_wan.ipv6_addr_gw[2];
+ data_iptype->ipv6_addr_gw[3] = event_wan.ipv6_addr_gw[3];
+ IPACMDBG_H("default gw ipv4 (%x)\n", data_iptype->ipv4_addr_gw);
+ IPACMDBG_H("IPV6 gateway: %08x:%08x:%08x:%08x \n",
+ data_iptype->ipv6_addr_gw[0], data_iptype->ipv6_addr_gw[1], data_iptype->ipv6_addr_gw[2], data_iptype->ipv6_addr_gw[3]);
+#endif
IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_ADD: fid(%d) tether_fid(%d) ip-type(%d)\n", data_iptype->if_index,
data_iptype->if_index_tether, data_iptype->iptype);
evt_data.event = IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT;
diff --git a/ipacm/src/IPACM_Routing.cpp b/ipacm/src/IPACM_Routing.cpp
index 7ae6131..2a2555a 100644
--- a/ipacm/src/IPACM_Routing.cpp
+++ b/ipacm/src/IPACM_Routing.cpp
@@ -176,8 +176,10 @@
IPACMERR("IPA_IOCTL_GET_RT_TBL ioctl failed, routingTable =0x%p, retval=0x%x.\n", routingTable, retval);
return false;
}
-
IPACMDBG_H("IPA_IOCTL_GET_RT_TBL ioctl issued to IPA routing block.\n");
+ /* put routing table right after successfully get routing table */
+ PutRoutingTable(routingTable->hdl);
+
return true;
}
diff --git a/ipacm/src/IPACM_Wan.cpp b/ipacm/src/IPACM_Wan.cpp
index 5aae426..4ee6c10 100644
--- a/ipacm/src/IPACM_Wan.cpp
+++ b/ipacm/src/IPACM_Wan.cpp
@@ -55,6 +55,7 @@
bool IPACM_Wan::wan_up_v6 = false;
uint8_t IPACM_Wan::xlat_mux_id = 0;
+uint32_t IPACM_Wan::curr_wan_ip = 0;
int IPACM_Wan::num_v4_flt_rule = 0;
int IPACM_Wan::num_v6_flt_rule = 0;
@@ -118,6 +119,8 @@
memset(ipv6_prefix, 0, sizeof(ipv6_prefix));
memset(wan_v6_addr_gw, 0, sizeof(wan_v6_addr_gw));
ext_prop = NULL;
+ is_ipv6_frag_firewall_flt_rule_installed = false;
+ ipv6_frag_firewall_flt_rule_hdl = 0;
num_wan_client = 0;
header_name_count = 0;
@@ -204,36 +207,39 @@
return IPACM_SUCCESS;
}
+ /* Update the IP Type. */
+ config_ip_type(data->iptype);
+
if (data->iptype == IPA_IP_v6)
{
- for(num_ipv6_addr=0;num_ipv6_addr<num_dft_rt_v6;num_ipv6_addr++)
- {
- if((ipv6_addr[num_ipv6_addr][0] == data->ipv6_addr[0]) &&
- (ipv6_addr[num_ipv6_addr][1] == data->ipv6_addr[1]) &&
- (ipv6_addr[num_ipv6_addr][2] == data->ipv6_addr[2]) &&
- (ipv6_addr[num_ipv6_addr][3] == data->ipv6_addr[3]))
- {
- IPACMDBG_H("find matched ipv6 address, index:%d \n", num_ipv6_addr);
- return IPACM_SUCCESS;
- break;
- }
- }
- rt_rule = (struct ipa_ioc_add_rt_rule *)
- calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
- NUM_RULES * sizeof(struct ipa_rt_rule_add));
+ for(num_ipv6_addr=0;num_ipv6_addr<num_dft_rt_v6;num_ipv6_addr++)
+ {
+ if((ipv6_addr[num_ipv6_addr][0] == data->ipv6_addr[0]) &&
+ (ipv6_addr[num_ipv6_addr][1] == data->ipv6_addr[1]) &&
+ (ipv6_addr[num_ipv6_addr][2] == data->ipv6_addr[2]) &&
+ (ipv6_addr[num_ipv6_addr][3] == data->ipv6_addr[3]))
+ {
+ IPACMDBG_H("find matched ipv6 address, index:%d \n", num_ipv6_addr);
+ return IPACM_SUCCESS;
+ break;
+ }
+ }
+ rt_rule = (struct ipa_ioc_add_rt_rule *)
+ calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
+ NUM_RULES * sizeof(struct ipa_rt_rule_add));
- if (!rt_rule)
- {
- IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n");
- return IPACM_FAILURE;
- }
+ if (!rt_rule)
+ {
+ IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n");
+ return IPACM_FAILURE;
+ }
- rt_rule->commit = 1;
- rt_rule->num_rules = NUM_RULES;
- rt_rule->ip = data->iptype;
- strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_v6.name);
+ rt_rule->commit = 1;
+ rt_rule->num_rules = NUM_RULES;
+ rt_rule->ip = data->iptype;
+ strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_v6.name, sizeof(rt_rule->rt_tbl_name));
- rt_rule_entry = &rt_rule->rules[0];
+ rt_rule_entry = &rt_rule->rules[0];
if(m_is_sta_mode == Q6_WAN)
{
strlcpy(hdr.name, tx_prop->tx[0].hdr_name, sizeof(hdr.name));
@@ -245,7 +251,7 @@
}
rt_rule_entry->rule.hdr_hdl = hdr.hdl;
}
- rt_rule_entry->at_rear = false;
+ rt_rule_entry->at_rear = false;
if(m_is_sta_mode == Q6_WAN)
{
rt_rule_entry->rule.dst = IPA_CLIENT_APPS_WAN_CONS;
@@ -254,62 +260,59 @@
{
rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS;
}
- rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
- rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = data->ipv6_addr[0];
- rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = data->ipv6_addr[1];
- rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = data->ipv6_addr[2];
- rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = data->ipv6_addr[3];
- rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
- rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
- rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
- rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
- ipv6_addr[num_dft_rt_v6][0] = data->ipv6_addr[0];
- ipv6_addr[num_dft_rt_v6][1] = data->ipv6_addr[1];
- ipv6_addr[num_dft_rt_v6][2] = data->ipv6_addr[2];
- ipv6_addr[num_dft_rt_v6][3] = data->ipv6_addr[3];
+ rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
+ rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = data->ipv6_addr[0];
+ rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = data->ipv6_addr[1];
+ rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = data->ipv6_addr[2];
+ rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = data->ipv6_addr[3];
+ rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
+ rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
+ rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
+ rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
+ ipv6_addr[num_dft_rt_v6][0] = data->ipv6_addr[0];
+ ipv6_addr[num_dft_rt_v6][1] = data->ipv6_addr[1];
+ ipv6_addr[num_dft_rt_v6][2] = data->ipv6_addr[2];
+ ipv6_addr[num_dft_rt_v6][3] = data->ipv6_addr[3];
#ifdef FEATURE_IPA_V3
rt_rule_entry->rule.hashable = false;
#endif
- if (false == m_routing.AddRoutingRule(rt_rule))
- {
- IPACMERR("Routing rule addition failed!\n");
- res = IPACM_FAILURE;
- goto fail;
- }
- else if (rt_rule_entry->status)
- {
- IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
- res = rt_rule_entry->status;
- goto fail;
- }
- dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6] = rt_rule_entry->rt_rule_hdl;
+ if (false == m_routing.AddRoutingRule(rt_rule))
+ {
+ IPACMERR("Routing rule addition failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ else if (rt_rule_entry->status)
+ {
+ IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
+ res = rt_rule_entry->status;
+ goto fail;
+ }
+ dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6] = rt_rule_entry->rt_rule_hdl;
- /* setup same rule for v6_wan table*/
- strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name);
- if (false == m_routing.AddRoutingRule(rt_rule))
- {
- IPACMERR("Routing rule addition failed!\n");
- res = IPACM_FAILURE;
- goto fail;
- }
- else if (rt_rule_entry->status)
- {
- IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
- res = rt_rule_entry->status;
- goto fail;
- }
- dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1] = rt_rule_entry->rt_rule_hdl;
+ /* setup same rule for v6_wan table*/
+ strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, sizeof(rt_rule->rt_tbl_name));
+ if (false == m_routing.AddRoutingRule(rt_rule))
+ {
+ IPACMERR("Routing rule addition failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ else if (rt_rule_entry->status)
+ {
+ IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
+ res = rt_rule_entry->status;
+ goto fail;
+ }
+ dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1] = rt_rule_entry->rt_rule_hdl;
- IPACMDBG_H("ipv6 wan iface rt-rule hdl=0x%x hdl=0x%x, num_dft_rt_v6: %d \n",
- dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6],
- dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1],num_dft_rt_v6);
-
- /* Update the IP Type. */
- config_ip_type(data->iptype);
+ IPACMDBG_H("ipv6 wan iface rt-rule hdl=0x%x hdl=0x%x, num_dft_rt_v6: %d \n",
+ dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6],
+ dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1],num_dft_rt_v6);
/* add default filtering rules when wan-iface get global v6-prefix */
- if (num_dft_rt_v6 == 1)
- {
+ if (num_dft_rt_v6 == 1)
+ {
if(m_is_sta_mode == Q6_WAN)
{
modem_ipv6_pdn_index = num_ipv6_modem_pdn;
@@ -321,7 +324,7 @@
{
init_fl_rule(data->iptype);
}
- }
+ }
/* add WAN DL interface IP specific flt rule for IPv6 when backhaul is not Q6 */
if(m_is_sta_mode != Q6_WAN)
@@ -420,7 +423,7 @@
if (!rt_rule)
{
- IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n");
+ IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n");
return IPACM_FAILURE;
}
@@ -447,7 +450,7 @@
rt_rule_entry->at_rear = false;
rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
/* still need setup v4 default routing rule to A5*/
- strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name);
+ strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name, sizeof(rt_rule->rt_tbl_name));
rt_rule_entry->rule.attrib.u.v4.dst_addr = data->ipv4_addr;
rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
#ifdef FEATURE_IPA_V3
@@ -469,9 +472,6 @@
IPACMDBG_H("ipv4 wan iface rt-rule hdll=0x%x\n", dft_rt_rule_hdl[0]);
/* initial multicast/broadcast/fragment filter rule */
- /* Update the IP Type. */
- config_ip_type(data->iptype);
-
/* only do one time */
if(!wan_v4_addr_set)
{
@@ -491,6 +491,10 @@
wan_v4_addr = data->ipv4_addr;
wan_v4_addr_set = true;
+
+ if (m_is_sta_mode == Q6_WAN)
+ curr_wan_ip = data->ipv4_addr;
+
IPACMDBG_H("Receved wan ipv4-addr:0x%x\n",wan_v4_addr);
}
@@ -715,7 +719,15 @@
{
if (active_v4 == false)
{
+#ifdef IPA_WAN_MSG_IPv6_ADDR_GW_LEN
+ IPACMDBG_H("adding routing table(upstream), dev (%s) ip-type(%d) default gw (%x)\n", dev_name,data->iptype, wan_v4_addr_gw);
+ wan_v4_addr_gw = data->ipv4_addr_gw;
+ wan_v4_addr_gw_set = true;
+ /* Check & construct STA header */
+ handle_sta_header_add_evt();
+#else
IPACMDBG_H("adding routing table(upstream), dev (%s) ip-type(%d)\n", dev_name,data->iptype);
+#endif
handle_route_add_evt(data->iptype);
}
#ifdef FEATURE_IPA_ANDROID
@@ -725,9 +737,26 @@
}
else if ((data->iptype == IPA_IP_v6) && (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX))
{
+ if(ipv6_prefix[0] == 0 && ipv6_prefix[1] == 0)
+ {
+ IPACMDBG_H("IPv6 default route comes earlier than global IP, ignore.\n");
+ return;
+ }
+
if (active_v6 == false)
{
IPACMDBG_H("\n get default v6 route (dst:00.00.00.00) upstream\n");
+#ifdef IPA_WAN_MSG_IPv6_ADDR_GW_LEN
+ IPACMDBG_H(" IPV6 gateway: %08x:%08x:%08x:%08x \n",
+ data->ipv6_addr_gw[0], data->ipv6_addr_gw[1], data->ipv6_addr_gw[2], data->ipv6_addr_gw[3]);
+ wan_v6_addr_gw[0] = data->ipv6_addr_gw[0];
+ wan_v6_addr_gw[1] = data->ipv6_addr_gw[1];
+ wan_v6_addr_gw[2] = data->ipv6_addr_gw[2];
+ wan_v6_addr_gw[3] = data->ipv6_addr_gw[3];
+ wan_v6_addr_gw_set = true;
+ /* Check & construct STA header */
+ handle_sta_header_add_evt();
+#endif
handle_route_add_evt(data->iptype);
}
#ifdef FEATURE_IPA_ANDROID
@@ -742,7 +771,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 */
+ wan_v4_addr_gw_set = false;
if(m_is_sta_mode == Q6_WAN)
{
del_wan_firewall_rule(IPA_IP_v4);
@@ -785,7 +814,7 @@
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 */
+ wan_v4_addr_gw_set = false;
#ifdef FEATURE_IPA_ANDROID
/* using ipa_if_index, not netdev_index */
post_wan_down_tether_evt(data->iptype, iface_ipa_index_query(data->if_index_tether));
@@ -880,6 +909,12 @@
(!data->ipv6_addr[0]) && (!data->ipv6_addr[1]) && (!data->ipv6_addr[2]) && (!data->ipv6_addr[3]) &&
(active_v6 == false) && (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX))
{
+ if(ipv6_prefix[0] == 0 && ipv6_prefix[1] == 0)
+ {
+ IPACMDBG_H("IPv6 default route comes earlier than global IP, ignore.\n");
+ return;
+ }
+
IPACMDBG_H("\n get default v6 route (dst:00.00.00.00)\n");
IPACMDBG_H(" IPV6 dst: %08x:%08x:%08x:%08x \n",
data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]);
@@ -1201,8 +1236,6 @@
is_default_gateway = true;
IPACMDBG_H("Default route is added to iface %s.\n", dev_name);
- memcpy(backhaul_ipv6_prefix, ipv6_prefix, sizeof(backhaul_ipv6_prefix));
- IPACMDBG_H("Setup backhaul ipv6 prefix to be 0x%08x%08x.\n", backhaul_ipv6_prefix[0], backhaul_ipv6_prefix[1]);
if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode == BRIDGE)
{
@@ -1336,12 +1369,12 @@
/* use the STA-header handler */
if (iptype == IPA_IP_v4)
{
- strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.name);
+ strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.name, sizeof(rt_rule->rt_tbl_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);
+ strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_v6.name, sizeof(rt_rule->rt_tbl_name));
rt_rule_entry->rule.hdr_hdl = hdr_hdl_sta_v6;
}
@@ -1412,7 +1445,7 @@
if (iptype == IPA_IP_v6)
{
- strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name);
+ strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, sizeof(rt_rule->rt_tbl_name));
memset(rt_rule_entry, 0, sizeof(struct ipa_rt_rule_add));
rt_rule_entry->at_rear = true;
if(m_is_sta_mode == Q6_WAN)
@@ -1528,6 +1561,9 @@
}
else
{
+ memcpy(backhaul_ipv6_prefix, ipv6_prefix, sizeof(backhaul_ipv6_prefix));
+ IPACMDBG_H("Setup backhaul ipv6 prefix to be 0x%08x%08x.\n", backhaul_ipv6_prefix[0], backhaul_ipv6_prefix[1]);
+
IPACM_Wan::wan_up_v6 = true;
active_v6 = true;
memcpy(IPACM_Wan::wan_up_dev_name,
@@ -1953,6 +1989,7 @@
{
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;
+ is_ipv6_frag_firewall_flt_rule_installed = true;
IPACMDBG_H("Installed IPv6 frag firewall rule, handle %d.\n", ipv6_frag_firewall_flt_rule_hdl);
}
}
@@ -3102,52 +3139,6 @@
return IPACM_SUCCESS;
}
-void IPACM_Wan::config_ip_type(ipa_ip_type iptype)
-{
-
- /* update the iface ip-type to be IPA_IP_v4, IPA_IP_v6 or both*/
- if (iptype == IPA_IP_v4)
- {
-
- if ((ip_type == IPA_IP_v4) || (ip_type == IPA_IP_MAX))
- {
- IPACMDBG_H(" interface(%s:%d) already in ip-type %d\n", dev_name, ipa_if_num, ip_type);
- return;
- }
-
- if (ip_type == IPA_IP_v6)
- {
- ip_type = IPA_IP_MAX;
- }
- else
- {
- ip_type = IPA_IP_v4;
- }
- IPACMDBG_H(" interface(%s:%d) now ip-type is %d\n", dev_name, ipa_if_num, ip_type);
- }
- else
- {
- if ((ip_type == IPA_IP_v6) || (ip_type == IPA_IP_MAX))
- {
- IPACMDBG_H(" interface(%s:%d) already in ip-type %d\n", dev_name, ipa_if_num, ip_type);
- return;
- }
-
- if (ip_type == IPA_IP_v4)
- {
- ip_type = IPA_IP_MAX;
- }
- else
- {
- ip_type = IPA_IP_v6;
- }
-
- IPACMDBG_H(" interface(%s:%d) now ip-type is %d\n", dev_name, ipa_if_num, ip_type);
- }
-
- return;
-}
-
int IPACM_Wan::init_fl_rule_ex(ipa_ip_type iptype)
{
int res = IPACM_SUCCESS;
@@ -3878,7 +3869,7 @@
}
IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
- if (firewall_config.firewall_enable == true &&
+ if (is_ipv6_frag_firewall_flt_rule_installed &&
check_dft_firewall_rules_attr_mask(&firewall_config))
{
if (m_filtering.DeleteFilteringHdls(&ipv6_frag_firewall_flt_rule_hdl, IPA_IP_v6, 1) == false)
@@ -3886,6 +3877,7 @@
IPACMERR("Error deleting IPv6 frag filtering rules.\n");
return IPACM_FAILURE;
}
+ is_ipv6_frag_firewall_flt_rule_installed = false;
IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
}
num_firewall_v6 = 0;
diff --git a/ipacm/src/IPACM_Wlan.cpp b/ipacm/src/IPACM_Wlan.cpp
index 375a718..00754a1 100644
--- a/ipacm/src/IPACM_Wlan.cpp
+++ b/ipacm/src/IPACM_Wlan.cpp
@@ -157,7 +157,7 @@
IPACMDBG_H("Received IPA_WLAN_LINK_DOWN_EVENT\n");
handle_down_evt();
/* reset the AP-iface category to unknown */
- ipa_if_cate = UNKNOWN_IF;
+ IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat = UNKNOWN_IF;
IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface
IPACM_Wlan::total_num_wifi_clients = (IPACM_Wlan::total_num_wifi_clients) - \
(num_wifi_client);
@@ -284,6 +284,7 @@
{
if((data->iptype == IPA_IP_v6 || data->iptype == IPA_IP_MAX) && num_dft_rt_v6 == 1)
{
+ memcpy(ipv6_prefix, IPACM_Wan::backhaul_ipv6_prefix, sizeof(ipv6_prefix));
install_ipv6_prefix_flt_rule(IPACM_Wan::backhaul_ipv6_prefix);
if(IPACM_Wan::backhaul_is_sta_mode == false)
@@ -356,6 +357,7 @@
{
if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
{
+ memcpy(ipv6_prefix, data_wan_tether->ipv6_prefix, sizeof(ipv6_prefix));
install_ipv6_prefix_flt_rule(data_wan_tether->ipv6_prefix);
if(data_wan_tether->is_sta == false)
@@ -463,6 +465,7 @@
IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta);
if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
{
+ memcpy(ipv6_prefix, data_wan->ipv6_prefix, sizeof(ipv6_prefix));
install_ipv6_prefix_flt_rule(data_wan->ipv6_prefix);
if(data_wan->is_sta == false)
@@ -1038,6 +1041,8 @@
{
int clnt_indx;
int v6_num;
+ uint32_t ipv6_link_local_prefix = 0xFE800000;
+ uint32_t ipv6_link_local_prefix_mask = 0xFFC00000;
IPACMDBG_H("number of wifi clients: %d\n", num_wifi_client);
IPACMDBG_H(" event MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
@@ -1097,22 +1102,29 @@
if ((data->ipv6_addr[0] != 0) || (data->ipv6_addr[1] != 0) ||
(data->ipv6_addr[2] != 0) || (data->ipv6_addr[3] || 0)) /* check if all 0 not valid ipv6 address */
{
- IPACMDBG_H("ipv6 address: 0x%x:%x:%x:%x\n", data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]);
- if(get_client_memptr(wlan_client, clnt_indx)->ipv6_set < IPV6_NUM_ADDR)
- {
+ IPACMDBG_H("ipv6 address: 0x%x:%x:%x:%x\n", data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]);
+ if( (data->ipv6_addr[0] & ipv6_link_local_prefix_mask) != (ipv6_link_local_prefix & ipv6_link_local_prefix_mask) &&
+ memcmp(ipv6_prefix, data->ipv6_addr, sizeof(ipv6_prefix)) != 0)
+ {
+ IPACMDBG_H("This IPv6 address is not global IPv6 address with correct prefix, ignore.\n");
+ return IPACM_FAILURE;
+ }
+
+ if(get_client_memptr(wlan_client, clnt_indx)->ipv6_set < IPV6_NUM_ADDR)
+ {
for(v6_num=0;v6_num < get_client_memptr(wlan_client, clnt_indx)->ipv6_set;v6_num++)
- {
- if( data->ipv6_addr[0] == get_client_memptr(wlan_client, clnt_indx)->v6_addr[v6_num][0] &&
+ {
+ if( data->ipv6_addr[0] == get_client_memptr(wlan_client, clnt_indx)->v6_addr[v6_num][0] &&
data->ipv6_addr[1] == get_client_memptr(wlan_client, clnt_indx)->v6_addr[v6_num][1] &&
data->ipv6_addr[2]== get_client_memptr(wlan_client, clnt_indx)->v6_addr[v6_num][2] &&
data->ipv6_addr[3] == get_client_memptr(wlan_client, clnt_indx)->v6_addr[v6_num][3])
- {
+ {
IPACMDBG_H("Already see this ipv6 addr for client:%d\n", clnt_indx);
return IPACM_FAILURE; /* not setup the RT rules*/
break;
- }
- }
+ }
+ }
/* not see this ipv6 before for wifi client*/
get_client_memptr(wlan_client, clnt_indx)->v6_addr[get_client_memptr(wlan_client, clnt_indx)->ipv6_set][0] = data->ipv6_addr[0];
@@ -1123,8 +1135,8 @@
}
else
{
- IPACMDBG_H("Already got 3 ipv6 addr for client:%d\n", clnt_indx);
- return IPACM_FAILURE; /* not setup the RT rules*/
+ IPACMDBG_H("Already got %d ipv6 addr for client:%d\n", IPV6_NUM_ADDR, clnt_indx);
+ return IPACM_FAILURE; /* not setup the RT rules*/
}
}
}
diff --git a/ipacm/src/IPACM_Xml.cpp b/ipacm/src/IPACM_Xml.cpp
index faae5b2..073dc98 100644
--- a/ipacm/src/IPACM_Xml.cpp
+++ b/ipacm/src/IPACM_Xml.cpp
@@ -174,7 +174,8 @@
IPACM_util_icmp_string((char*)xml_node->name, SUBNET_TAG) == 0 ||
IPACM_util_icmp_string((char*)xml_node->name, IPACMALG_TAG) == 0 ||
IPACM_util_icmp_string((char*)xml_node->name, ALG_TAG) == 0 ||
- IPACM_util_icmp_string((char*)xml_node->name, IPACMNat_TAG) == 0)
+ IPACM_util_icmp_string((char*)xml_node->name, IPACMNat_TAG) == 0 ||
+ IPACM_util_icmp_string((char*)xml_node->name, IP_PassthroughFlag_TAG) == 0)
{
if (0 == IPACM_util_icmp_string((char*)xml_node->name, IFACE_TAG))
{
@@ -196,6 +197,27 @@
/* go to child */
ret_val = ipacm_cfg_xml_parse_tree(xml_node->children, config);
}
+ else if (IPACM_util_icmp_string((char*)xml_node->name, IP_PassthroughMode_TAG) == 0)
+ {
+ IPACMDBG_H("inside IP Passthrough\n");
+ 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 (atoi(content_buf))
+ {
+ config->ip_passthrough_mode = true;
+ IPACMDBG_H("Passthrough enable %d buf(%d)\n", config->ip_passthrough_mode, atoi(content_buf));
+ }
+ else
+ {
+ config->ip_passthrough_mode = false;
+ IPACMDBG_H("Passthrough enable %d buf(%d)\n", config->ip_passthrough_mode, atoi(content_buf));
+ }
+ }
+ }
else if (IPACM_util_icmp_string((char*)xml_node->name, ODUMODE_TAG) == 0)
{
IPACMDBG_H("inside ODU-XML\n");
diff --git a/ipacm/src/IPACM_cfg.xml b/ipacm/src/IPACM_cfg.xml
index d16d2ed..9bac7a4 100644
--- a/ipacm/src/IPACM_cfg.xml
+++ b/ipacm/src/IPACM_cfg.xml
@@ -49,6 +49,11 @@
<Category>WAN</Category>
</Iface>
<Iface>
+ <Name>softap0</Name>
+ <Category>UNKNOWN</Category>
+ <WlanMode>full</WlanMode>
+ </Iface>
+ <Iface>
<Name>wlan0</Name>
<Category>UNKNOWN</Category>
<WlanMode>full</WlanMode>
@@ -59,6 +64,16 @@
<WlanMode>full</WlanMode>
</Iface>
<Iface>
+ <Name>wlan2</Name>
+ <Category>UNKNOWN</Category>
+ <WlanMode>full</WlanMode>
+ </Iface>
+ <Iface>
+ <Name>wlan3</Name>
+ <Category>UNKNOWN</Category>
+ <WlanMode>full</WlanMode>
+ </Iface>
+ <Iface>
<Name>eth0</Name>
<Category>ODU</Category>
</Iface>
@@ -67,6 +82,9 @@
<Category>VIRTUAL</Category>
</Iface>
</IPACMIface>
+ <IPPassthroughFlag>
+ <IPPassthroughMode>0</IPPassthroughMode>
+ </IPPassthroughFlag>
<IPACMPrivateSubnet>
<Subnet>
<SubnetAddress>192.168.225.0</SubnetAddress>