IPACM: Add support to get tether stats
This changes provides the support to
to get tether stats.
Change-Id: I668a8fa3ffbab2c714d09543e6d2a7e67ff55eff
diff --git a/ipacm/inc/IPACM_Defs.h b/ipacm/inc/IPACM_Defs.h
index b424d97..559daca 100644
--- a/ipacm/inc/IPACM_Defs.h
+++ b/ipacm/inc/IPACM_Defs.h
@@ -190,6 +190,10 @@
IPA_WAN_XLAT_CONNECT_EVENT, /* 53 ipacm_event_data_fid */
IPA_TETHERING_STATS_UPDATE_EVENT, /* 54 ipacm_event_data_fid */
IPA_NETWORK_STATS_UPDATE_EVENT, /* 55 ipacm_event_data_fid */
+ IPA_HANDLE_WAN_UP_TETHER, /* 56 ipacm_event_iface_up_tehter */
+ IPA_HANDLE_WAN_DOWN_TETHER, /* 57 ipacm_event_iface_up_tehter */
+ IPA_HANDLE_WAN_UP_V6_TETHER, /* 58 ipacm_event_iface_up_tehter */
+ IPA_HANDLE_WAN_DOWN_V6_TETHER, /* 59 ipacm_event_iface_up_tehter */
IPACM_EVENT_MAX
} ipa_cm_event_id;
@@ -292,6 +296,7 @@
typedef struct _ipacm_event_data_iptype
{
int if_index;
+ int if_index_tether;
enum ipa_ip_type iptype;
} ipacm_event_data_iptype;
@@ -330,6 +335,13 @@
uint8_t xlat_mux_id;
}ipacm_event_iface_up;
+typedef struct _ipacm_event_iface_up_tether
+{
+ uint32_t if_index_tether;
+ uint32_t ipv6_prefix[2];
+ bool is_sta;
+}ipacm_event_iface_up_tehter;
+
typedef enum
{
Q6_WAN = 0,
diff --git a/ipacm/inc/IPACM_Lan.h b/ipacm/inc/IPACM_Lan.h
index 94a1c6d..3579567 100644
--- a/ipacm/inc/IPACM_Lan.h
+++ b/ipacm/inc/IPACM_Lan.h
@@ -315,6 +315,9 @@
/* handle tethering stats */
int handle_tethering_stats_event(ipa_get_data_stats_resp_msg_v01 *data);
+ /* handle tethering client */
+ int handle_tethering_client(bool reset, ipacm_client_enum ipa_client);
+
lan2lan_flt_rule_hdl lan2lan_flt_rule_hdl_v4[MAX_OFFLOAD_PAIR];
lan2lan_flt_rule_hdl lan2lan_flt_rule_hdl_v6[MAX_OFFLOAD_PAIR];
diff --git a/ipacm/inc/IPACM_Wan.h b/ipacm/inc/IPACM_Wan.h
index 159cc46..65f788f 100644
--- a/ipacm/inc/IPACM_Wan.h
+++ b/ipacm/inc/IPACM_Wan.h
@@ -97,18 +97,43 @@
static uint8_t xlat_mux_id;
/* IPACM interface name */
static char wan_up_dev_name[IF_NAME_LEN];
-
IPACM_Wan(int, ipacm_wan_iface_type, uint8_t *);
virtual ~IPACM_Wan();
- static bool isWanUP()
+ static bool isWanUP(int ipa_if_num_tether)
{
+#ifdef FEATURE_IPA_ANDROID
+ int i;
+ for (i=1; i < ipa_if_num_tether_v4_total;i++)
+ {
+ if (ipa_if_num_tether_v4[i] == ipa_if_num_tether)
+ {
+ return wan_up;
+ break;
+ }
+ }
+ return false;
+#else
return wan_up;
+#endif
}
- static bool isWanUP_V6()
+ static bool isWanUP_V6(int ipa_if_num_tether)
{
+#ifdef FEATURE_IPA_ANDROID
+ int i;
+ for (i=1; i < ipa_if_num_tether_v6_total;i++)
+ {
+ if (ipa_if_num_tether_v6[i] == ipa_if_num_tether)
+ {
+ return wan_up_v6;
+ break;
+ }
+ }
+ return false;
+#else
return wan_up_v6;
+#endif
}
static bool getXlat_Mux_Id()
@@ -137,6 +162,13 @@
{
return backhaul_is_wan_bridge;
}
+#ifdef FEATURE_IPA_ANDROID
+ /* IPACM interface id */
+ static int ipa_if_num_tether_v4_total;
+ static int ipa_if_num_tether_v4[IPA_MAX_IFACE_ENTRIES];
+ static int ipa_if_num_tether_v6_total;
+ static int ipa_if_num_tether_v6[IPA_MAX_IFACE_ENTRIES];
+#endif
private:
@@ -341,6 +373,12 @@
bool check_dft_firewall_rules_attr_mask(IPACM_firewall_conf_t *firewall_config);
+#ifdef FEATURE_IPA_ANDROID
+ /* wan posting supported tether_iface */
+ int post_wan_up_tether_evt(ipa_ip_type iptype, int ipa_if_num_tether);
+
+ int post_wan_down_tether_evt(ipa_ip_type iptype, int ipa_if_num_tether);
+#endif
int config_dft_firewall_rules(ipa_ip_type iptype);
/* configure the initial firewall filter rules */
diff --git a/ipacm/src/IPACM_Config.cpp b/ipacm/src/IPACM_Config.cpp
index 24890ed..f7d764a 100644
--- a/ipacm/src/IPACM_Config.cpp
+++ b/ipacm/src/IPACM_Config.cpp
@@ -150,7 +150,7 @@
{
IPACMERR("Unable to allocate iface_table memory.\n");
ret = IPACM_FAILURE;
- goto fail;;
+ goto fail;
}
for (i = 0; i < cfg->iface_config.num_iface_entries; i++)
diff --git a/ipacm/src/IPACM_IfaceManager.cpp b/ipacm/src/IPACM_IfaceManager.cpp
index 03233b5..3024ce6 100644
--- a/ipacm/src/IPACM_IfaceManager.cpp
+++ b/ipacm/src/IPACM_IfaceManager.cpp
@@ -214,10 +214,17 @@
IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT, lan);
IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, lan);
IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, lan);
+#ifdef FEATURE_IPA_ANDROID
+ IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_TETHER, lan);
+ IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6_TETHER, lan);
+ IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_TETHER, lan);
+ IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6_TETHER, lan);
+#else
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP, lan);
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6, lan);
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN, lan);
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6, lan);
+#endif
IPACM_EvtDispatcher::registr(IPA_CFG_CHANGE_EVENT, lan); // register for IPA_CFG_CHANGE event
IPACM_EvtDispatcher::registr(IPA_PRIVATE_SUBNET_CHANGE_EVENT, lan); // register for IPA_PRIVATE_SUBNET_CHANGE_EVENT event
#ifdef FEATURE_ETH_BRIDGE_LE
@@ -326,10 +333,17 @@
IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, wl);
IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, wl);
IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, wl);
+#ifdef FEATURE_IPA_ANDROID
+ IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_TETHER, wl);
+ IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6_TETHER, wl);
+ IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_TETHER, wl);
+ IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6_TETHER, wl);
+#else
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP, wl);
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6, wl);
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN, wl);
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6, wl);
+#endif
IPACM_EvtDispatcher::registr(IPA_PRIVATE_SUBNET_CHANGE_EVENT, wl); // register for IPA_PRIVATE_SUBNET_CHANGE_EVENT event
#ifdef FEATURE_ETH_BRIDGE_LE
IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_LAN_CLIENT_ADD_EVENT, wl);
@@ -371,6 +385,7 @@
IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, w);
#ifdef FEATURE_IPA_ANDROID
IPACM_EvtDispatcher::registr(IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT, w);
+ IPACM_EvtDispatcher::registr(IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT, w);
if(is_sta_mode == Q6_WAN)
{
IPACM_EvtDispatcher::registr(IPA_NETWORK_STATS_UPDATE_EVENT, w);
diff --git a/ipacm/src/IPACM_Lan.cpp b/ipacm/src/IPACM_Lan.cpp
index a8aff0b..4067e9f 100644
--- a/ipacm/src/IPACM_Lan.cpp
+++ b/ipacm/src/IPACM_Lan.cpp
@@ -296,6 +296,13 @@
lan_client_rt_from_wlan_info_count_v4 = 0;
lan_client_rt_from_wlan_info_count_v6 = 0;
+#ifdef FEATURE_IPA_ANDROID
+ /* set the IPA-client pipe enum */
+ if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == LAN_IF)
+ {
+ handle_tethering_client(false, IPACM_CLIENT_USB);
+ }
+#endif
return;
}
@@ -319,6 +326,7 @@
int ipa_interface_index;
ipacm_ext_prop* ext_prop;
ipacm_event_iface_up* data_wan;
+ ipacm_event_iface_up_tehter* data_wan_tether;
switch (event)
{
@@ -491,39 +499,39 @@
handle_private_subnet(data->iptype);
#endif
- if (IPACM_Wan::isWanUP())
+ if (IPACM_Wan::isWanUP(ipa_if_num))
{
if(data->iptype == IPA_IP_v4 || data->iptype == IPA_IP_MAX)
{
- if(IPACM_Wan::backhaul_is_sta_mode == false)
- {
+ if(IPACM_Wan::backhaul_is_sta_mode == false)
+ {
ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
handle_wan_up_ex(ext_prop, IPA_IP_v4,
IPACM_Wan::getXlat_Mux_Id());
}
- else
- {
- handle_wan_up(IPA_IP_v4);
+ else
+ {
+ handle_wan_up(IPA_IP_v4);
+ }
}
}
- }
- if(IPACM_Wan::isWanUP_V6())
+ if(IPACM_Wan::isWanUP_V6(ipa_if_num))
{
if((data->iptype == IPA_IP_v6 || data->iptype == IPA_IP_MAX) && num_dft_rt_v6 == 1)
{
install_ipv6_prefix_flt_rule(IPACM_Wan::backhaul_ipv6_prefix);
- if(IPACM_Wan::backhaul_is_sta_mode == false)
- {
+ if(IPACM_Wan::backhaul_is_sta_mode == 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);
+ }
}
}
- }
/* Post event to NAT */
if (data->iptype == IPA_IP_v4)
@@ -568,7 +576,107 @@
}
}
break;
+#ifdef FEATURE_IPA_ANDROID
+ case IPA_HANDLE_WAN_UP_TETHER:
+ IPACMDBG_H("Received IPA_HANDLE_WAN_UP_TETHER event\n");
+ data_wan_tether = (ipacm_event_iface_up_tehter*)param;
+ if(data_wan_tether == NULL)
+ {
+ IPACMERR("No event data is found.\n");
+ return;
+ }
+ IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d\n", data_wan_tether->is_sta,
+ data_wan_tether->if_index_tether);
+ if (iface_ipa_index_query(data_wan_tether->if_index_tether) == ipa_if_num)
+ {
+ if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
+ {
+ if(data_wan_tether->is_sta == false)
+ {
+ ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
+ handle_wan_up_ex(ext_prop, IPA_IP_v4, 0);
+ }
+ else
+ {
+ handle_wan_up(IPA_IP_v4);
+ }
+ }
+ }
+ break;
+
+ case IPA_HANDLE_WAN_UP_V6_TETHER:
+ IPACMDBG_H("Received IPA_HANDLE_WAN_UP_V6_TETHER event\n");
+
+ data_wan_tether = (ipacm_event_iface_up_tehter*)param;
+ if(data_wan_tether == NULL)
+ {
+ IPACMERR("No event data is found.\n");
+ return;
+ }
+ IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d\n", data_wan_tether->is_sta,
+ data_wan_tether->if_index_tether);
+ if (iface_ipa_index_query(data_wan_tether->if_index_tether) == ipa_if_num)
+ {
+ if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
+ {
+ install_ipv6_prefix_flt_rule(data_wan_tether->ipv6_prefix);
+ if(data_wan_tether->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);
+ }
+ }
+ }
+ break;
+
+ case IPA_HANDLE_WAN_DOWN_TETHER:
+ IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_TETHER event\n");
+ data_wan_tether = (ipacm_event_iface_up_tehter*)param;
+ if(data_wan_tether == NULL)
+ {
+ IPACMERR("No event data is found.\n");
+ return;
+ }
+ IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d\n", data_wan_tether->is_sta,
+ data_wan_tether->if_index_tether);
+ if (iface_ipa_index_query(data_wan_tether->if_index_tether) == ipa_if_num)
+ {
+ if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
+ {
+ handle_wan_down(data_wan_tether->is_sta);
+ }
+ }
+ break;
+
+ case IPA_HANDLE_WAN_DOWN_V6_TETHER:
+ IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_V6_TETHER event\n");
+ data_wan_tether = (ipacm_event_iface_up_tehter*)param;
+ if(data_wan_tether == NULL)
+ {
+ IPACMERR("No event data is found.\n");
+ return;
+ }
+ IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d\n", data_wan_tether->is_sta,
+ data_wan_tether->if_index_tether);
+ if (iface_ipa_index_query(data_wan_tether->if_index_tether) == ipa_if_num)
+ {
+ /* clean up v6 RT rules*/
+ IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_V6_TETHER in LAN-instance and need clean up client IPv6 address \n");
+ /* reset usb-client ipv6 rt-rules */
+ handle_lan_client_reset_rt(IPA_IP_v6);
+
+ if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
+ {
+ handle_wan_down_v6(data_wan_tether->is_sta);
+ }
+ }
+ break;
+#else
case IPA_HANDLE_WAN_UP:
IPACMDBG_H("Received IPA_HANDLE_WAN_UP event\n");
@@ -652,6 +760,7 @@
handle_wan_down_v6(data_wan->is_sta);
}
break;
+#endif
case IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT:
{
@@ -989,7 +1098,7 @@
case IPA_TETHERING_STATS_UPDATE_EVENT:
{
IPACMDBG_H("Received IPA_TETHERING_STATS_UPDATE_EVENT event.\n");
- if (IPACM_Wan::isWanUP() || IPACM_Wan::isWanUP_V6())
+ if (IPACM_Wan::isWanUP(ipa_if_num) || IPACM_Wan::isWanUP_V6(ipa_if_num))
{
if(IPACM_Wan::backhaul_is_sta_mode == false) /* LTE */
{
@@ -2694,13 +2803,13 @@
#endif
/* delete wan filter rule */
- if (IPACM_Wan::isWanUP() && rx_prop != NULL)
+ if (IPACM_Wan::isWanUP(ipa_if_num) && rx_prop != NULL)
{
IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_is_sta_mode);
handle_wan_down(IPACM_Wan::backhaul_is_sta_mode);
}
- if (IPACM_Wan::isWanUP_V6() && rx_prop != NULL)
+ if (IPACM_Wan::isWanUP_V6(ipa_if_num) && rx_prop != NULL)
{
IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_is_sta_mode);
handle_wan_down_v6(IPACM_Wan::backhaul_is_sta_mode);
@@ -3010,15 +3119,21 @@
/* Delete private subnet*/
#ifdef FEATURE_IPA_ANDROID
-if (ip_type != IPA_IP_v6)
-{
- IPACMDBG_H("current IPACM private subnet_addr number(%d)\n", IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
- IPACMDBG_H(" Delete IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
- if(IPACM_Iface::ipacmcfg->DelPrivateSubnet(if_ipv4_subnet, ipa_if_num) == false)
+ if (ip_type != IPA_IP_v6)
{
- IPACMERR(" can't Delete IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
+ IPACMDBG_H("current IPACM private subnet_addr number(%d)\n", IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
+ IPACMDBG_H(" Delete IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
+ if(IPACM_Iface::ipacmcfg->DelPrivateSubnet(if_ipv4_subnet, ipa_if_num) == false)
+ {
+ IPACMERR(" can't Delete IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
+ }
}
-}
+
+ /* reset the IPA-client pipe enum */
+ if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat != WAN_IF)
+ {
+ handle_tethering_client(true, IPACM_CLIENT_USB);
+ }
#endif /* defined(FEATURE_IPA_ANDROID)*/
fail:
if (odu_route_rule_v4_hdl != NULL)
@@ -3273,14 +3388,12 @@
IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
return IPACM_FAILURE;
}
-
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)
{
if (num_wan_ul_fl_rule_v6 > MAX_WAN_UL_FILTER_RULES)
@@ -3289,7 +3402,6 @@
close(fd);
return IPACM_FAILURE;
}
-
if (m_filtering.DeleteFilteringHdls(wan_ul_fl_rule_hdl_v6,
IPA_IP_v6, num_wan_ul_fl_rule_v6) == false)
{
@@ -3298,7 +3410,6 @@
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;
@@ -3312,7 +3423,6 @@
flt_index.retain_header = 0;
flt_index.embedded_call_mux_id_valid = 1;
flt_index.embedded_call_mux_id = IPACM_Iface::ipacmcfg->GetQmapId();
-
if(false == m_filtering.SendFilteringRuleIndex(&flt_index))
{
IPACMERR("Error sending filtering rule index, aborting...\n");
@@ -3331,7 +3441,6 @@
}
IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
}
-
close(fd);
return IPACM_SUCCESS;
}
@@ -6952,3 +7061,63 @@
}
return IPACM_SUCCESS;
}
+
+/*handle tether client */
+int IPACM_Lan::handle_tethering_client(bool reset, ipacm_client_enum ipa_client)
+{
+ int cnt, fd, ret = IPACM_SUCCESS;
+ int fd_wwan_ioctl = open(WWAN_QMI_IOCTL_DEVICE_NAME, O_RDWR);
+ wan_ioctl_set_tether_client_pipe tether_client;
+
+ if(fd_wwan_ioctl < 0)
+ {
+ IPACMERR("Failed to open %s.\n",WWAN_QMI_IOCTL_DEVICE_NAME);
+ return IPACM_FAILURE;
+ }
+
+ fd = open(IPA_DEVICE_NAME, O_RDWR);
+ if (fd < 0)
+ {
+ IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
+ close(fd_wwan_ioctl);
+ return IPACM_FAILURE;
+ }
+
+ memset(&tether_client, 0, sizeof(tether_client));
+ tether_client.reset_client = reset;
+ tether_client.ipa_client = ipa_client;
+
+ if(tx_prop != NULL)
+ {
+ tether_client.dl_dst_pipe_len = tx_prop->num_tx_props;
+ for (cnt = 0; cnt < tx_prop->num_tx_props; cnt++)
+ {
+ IPACMDBG_H("Tx(%d), dst_pipe: %d, ipa_pipe: %d\n",
+ cnt, tx_prop->tx[cnt].dst_pipe,
+ ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, tx_prop->tx[cnt].dst_pipe));
+ tether_client.dl_dst_pipe_list[cnt] = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, tx_prop->tx[cnt].dst_pipe);
+ }
+ }
+
+ if(rx_prop != NULL)
+ {
+ tether_client.ul_src_pipe_len = rx_prop->num_rx_props;
+ for (cnt = 0; cnt < rx_prop->num_rx_props; cnt++)
+ {
+ IPACMDBG_H("Rx(%d), src_pipe: %d, ipa_pipe: %d\n",
+ cnt, rx_prop->rx[cnt].src_pipe,
+ ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[cnt].src_pipe));
+ tether_client.ul_src_pipe_list[cnt] = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[cnt].src_pipe);
+ }
+ }
+
+ ret = ioctl(fd_wwan_ioctl, WAN_IOC_SET_TETHER_CLIENT_PIPE, &tether_client);
+ if (ret != 0)
+ {
+ IPACMERR("Failed set tether-client-pipe %p with ret %d\n ", &tether_client, ret);
+ }
+ IPACMDBG("Set tether-client-pipe %p\n", &tether_client);
+ close(fd);
+ close(fd_wwan_ioctl);
+ return ret;
+}
diff --git a/ipacm/src/IPACM_Main.cpp b/ipacm/src/IPACM_Main.cpp
index a86cfb8..67d9077 100644
--- a/ipacm/src/IPACM_Main.cpp
+++ b/ipacm/src/IPACM_Main.cpp
@@ -570,7 +570,7 @@
evt_data.event = IPA_LINK_DOWN_EVENT;
evt_data.evt_data = data_fid;
break;
- /* Add for 8994 Android case */
+ /* Add for 8994 Android case */
case WAN_UPSTREAM_ROUTE_ADD:
memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_wan_msg));
IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_ADD name: %s, tethered name: %s\n", event_wan.upstream_ifname, event_wan.tethered_ifname);
@@ -581,8 +581,10 @@
return NULL;
}
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;
- IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_ADD: fid(%d) ip-type(%d)\n", data_iptype->if_index, data_iptype->iptype);
+ 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;
evt_data.evt_data = data_iptype;
break;
@@ -596,14 +598,15 @@
return NULL;
}
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;
IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_DEL: fid(%d) ip-type(%d)\n", data_iptype->if_index, data_iptype->iptype);
evt_data.event = IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT;
evt_data.evt_data = data_iptype;
break;
- /* End of adding for 8994 Android case */
+ /* End of adding for 8994 Android case */
- /* Add for embms case */
+ /* Add for embms case */
case WAN_EMBMS_CONNECT:
memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_wan_msg));
IPACMDBG("Received WAN_EMBMS_CONNECT name: %s\n",event_wan.upstream_ifname);
diff --git a/ipacm/src/IPACM_Wan.cpp b/ipacm/src/IPACM_Wan.cpp
index 6381826..5e215ce 100644
--- a/ipacm/src/IPACM_Wan.cpp
+++ b/ipacm/src/IPACM_Wan.cpp
@@ -74,6 +74,14 @@
uint32_t IPACM_Wan::backhaul_ipv6_prefix[2];
+#ifdef FEATURE_IPA_ANDROID
+int IPACM_Wan::ipa_if_num_tether_v4_total = 0;
+int IPACM_Wan::ipa_if_num_tether_v6_total = 0;
+
+int IPACM_Wan::ipa_if_num_tether_v4[IPA_MAX_IFACE_ENTRIES];
+int IPACM_Wan::ipa_if_num_tether_v6[IPA_MAX_IFACE_ENTRIES];
+#endif
+
IPACM_Wan::IPACM_Wan(int iface_index,
ipacm_wan_iface_type is_sta_mode,
uint8_t *mac_addr) : IPACM_Iface(iface_index)
@@ -693,18 +701,27 @@
{
IPACMDBG_H("Received IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT (Android) for ip-type (%d)\n", data->iptype);
/* 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))
+ if ((data->iptype == IPA_IP_v4) && (ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX))
{
-// 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);
-
+ if (active_v4 == false)
+ {
+ IPACMDBG_H("adding routing table(upstream), dev (%s) ip-type(%d)\n", dev_name,data->iptype);
+ handle_route_add_evt(data->iptype);
+ }
+#ifdef FEATURE_IPA_ANDROID
+ post_wan_up_tether_evt(data->iptype, data->if_index_tether);
+#endif
}
- else if ((data->iptype == IPA_IP_v6) && (active_v6 == false) && (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX))
+ else if ((data->iptype == IPA_IP_v6) && (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX))
{
- IPACMDBG_H("\n get default v6 route (dst:00.00.00.00) upstream\n");
- handle_route_add_evt(data->iptype);
+ if (active_v6 == false)
+ {
+ IPACMDBG_H("\n get default v6 route (dst:00.00.00.00) upstream\n");
+ handle_route_add_evt(data->iptype);
+ }
+#ifdef FEATURE_IPA_ANDROID
+ post_wan_up_tether_evt(data->iptype, data->if_index_tether);
+#endif
}
}
else /* double check if current default iface is not itself */
@@ -757,6 +774,15 @@
{
IPACMDBG_H("get del default v4 route (dst:0.0.0.0)\n");
// wan_v4_addr_gw_set = false; /* android requires CnE change too */
+#ifdef FEATURE_IPA_ANDROID
+ post_wan_down_tether_evt(data->iptype, data->if_index_tether);
+ /* no any ipv4 tether iface support*/
+ if(IPACM_Wan::ipa_if_num_tether_v4_total != 0)
+ {
+ IPACMDBG_H("still have tether ipv4 client on upsteam iface\n");
+ return;
+ }
+#endif
if(m_is_sta_mode == Q6_WAN)
{
del_wan_firewall_rule(IPA_IP_v4);
@@ -771,6 +797,15 @@
}
else if ((data->iptype == IPA_IP_v6) && (active_v6 == true))
{
+#ifdef FEATURE_IPA_ANDROID
+ post_wan_down_tether_evt(data->iptype, data->if_index_tether);
+ /* no any ipv6 tether iface support*/
+ if(IPACM_Wan::ipa_if_num_tether_v6_total != 0)
+ {
+ IPACMDBG_H("still have tether ipv6 client on upsteam iface\n");
+ return;
+ }
+#endif
if(m_is_sta_mode == Q6_WAN)
{
del_wan_firewall_rule(IPA_IP_v6);
@@ -1502,6 +1537,147 @@
return IPACM_SUCCESS;
}
+#ifdef FEATURE_IPA_ANDROID
+/* wan default route/filter rule configuration */
+int IPACM_Wan::post_wan_up_tether_evt(ipa_ip_type iptype, int ipa_if_num_tether)
+{
+ ipacm_cmd_q_data evt_data;
+ ipacm_event_iface_up_tehter *wanup_data;
+
+ wanup_data = (ipacm_event_iface_up_tehter *)malloc(sizeof(ipacm_event_iface_up_tehter));
+ if (wanup_data == NULL)
+ {
+ IPACMERR("Unable to allocate memory\n");
+ return IPACM_FAILURE;
+ }
+ memset(wanup_data, 0, sizeof(ipacm_event_iface_up_tehter));
+
+ wanup_data->if_index_tether = ipa_if_num_tether;
+ if (m_is_sta_mode!=Q6_WAN)
+ {
+ wanup_data->is_sta = true;
+ }
+ else
+ {
+ wanup_data->is_sta = false;
+ }
+ IPACMDBG_H("Posting IPA_HANDLE_WAN_UP_TETHER with below information:\n");
+ IPACMDBG_H("tether_if_name:%s, is sta mode:%d\n",
+ IPACM_Iface::ipacmcfg->iface_table[iface_ipa_index_query(ipa_if_num_tether)].iface_name, wanup_data->is_sta);
+ memset(&evt_data, 0, sizeof(evt_data));
+
+ if (iptype == IPA_IP_v4)
+ {
+ evt_data.event = IPA_HANDLE_WAN_UP_TETHER;
+ /* Add support tether ifaces to its array*/
+ IPACM_Wan::ipa_if_num_tether_v4[IPACM_Wan::ipa_if_num_tether_v4_total] = ipa_if_num_tether;
+ IPACMDBG_H("adding tether iface(%s) ipa_if_num_tether_v4_total(%d)\n",
+ IPACM_Iface::ipacmcfg->iface_table[iface_ipa_index_query(ipa_if_num_tether)].iface_name,
+ IPACM_Wan::ipa_if_num_tether_v4_total);
+ IPACM_Wan::ipa_if_num_tether_v4_total++;
+ }
+ else
+ {
+ evt_data.event = IPA_HANDLE_WAN_UP_V6_TETHER;
+ memcpy(wanup_data->ipv6_prefix, ipv6_prefix, sizeof(wanup_data->ipv6_prefix));
+ /* Add support tether ifaces to its array*/
+ IPACM_Wan::ipa_if_num_tether_v6[IPACM_Wan::ipa_if_num_tether_v6_total] = ipa_if_num_tether;
+ IPACMDBG_H("adding tether iface(%s) ipa_if_num_tether_v6_total(%d)\n",
+ IPACM_Iface::ipacmcfg->iface_table[iface_ipa_index_query(ipa_if_num_tether)].iface_name,
+ IPACM_Wan::ipa_if_num_tether_v6_total);
+ IPACM_Wan::ipa_if_num_tether_v6_total++;
+ }
+ evt_data.evt_data = (void *)wanup_data;
+ IPACM_EvtDispatcher::PostEvt(&evt_data);
+
+ return IPACM_SUCCESS;
+}
+
+/* wan default route/filter rule configuration */
+int IPACM_Wan::post_wan_down_tether_evt(ipa_ip_type iptype, int ipa_if_num_tether)
+{
+ ipacm_cmd_q_data evt_data;
+ ipacm_event_iface_up_tehter *wandown_data;
+ int i, j;
+
+ wandown_data = (ipacm_event_iface_up_tehter *)malloc(sizeof(ipacm_event_iface_up_tehter));
+ if (wandown_data == NULL)
+ {
+ IPACMERR("Unable to allocate memory\n");
+ return IPACM_FAILURE;
+ }
+ memset(wandown_data, 0, sizeof(ipacm_event_iface_up_tehter));
+
+ wandown_data->if_index_tether = ipa_if_num_tether;
+ if (m_is_sta_mode!=Q6_WAN)
+ {
+ wandown_data->is_sta = true;
+ }
+ else
+ {
+ wandown_data->is_sta = false;
+ }
+ IPACMDBG_H("Posting IPA_HANDLE_WAN_DOWN_TETHER with below information:\n");
+ IPACMDBG_H("tether_if_name:%s, is sta mode:%d\n",
+ IPACM_Iface::ipacmcfg->iface_table[iface_ipa_index_query(ipa_if_num_tether)].iface_name, wandown_data->is_sta);
+ memset(&evt_data, 0, sizeof(evt_data));
+
+ if (iptype == IPA_IP_v4)
+ {
+ evt_data.event = IPA_HANDLE_WAN_DOWN_TETHER;
+ /* delete support tether ifaces to its array*/
+ for (i=0; i < IPACM_Wan::ipa_if_num_tether_v4_total; i++) //sky
+ {
+ if(IPACM_Wan::ipa_if_num_tether_v4[i] == ipa_if_num_tether)
+ {
+ IPACMDBG_H("Found tether client at position %d.\n", i);
+ break;
+ }
+ }
+ if(i == IPACM_Wan::ipa_if_num_tether_v4_total)
+ {
+ IPACMDBG_H("Not finding the tether client.\n");
+ free(wandown_data);
+ return IPACM_SUCCESS;
+ }
+ for(j = i+1; j < IPACM_Wan::ipa_if_num_tether_v4_total; j++)
+ {
+ IPACM_Wan::ipa_if_num_tether_v4[j-1] = IPACM_Wan::ipa_if_num_tether_v4[j];
+ }
+ IPACM_Wan::ipa_if_num_tether_v4_total--;
+ IPACMDBG_H("Now the total num of ipa_if_num_tether_v4_total is %d \n", IPACM_Wan::ipa_if_num_tether_v4_total);
+ }
+ else
+ {
+ evt_data.event = IPA_HANDLE_WAN_DOWN_V6_TETHER;
+ /* delete support tether ifaces to its array*/
+ for (i=0; i < IPACM_Wan::ipa_if_num_tether_v6_total; i++) //sky
+ {
+ if(IPACM_Wan::ipa_if_num_tether_v6[i] == ipa_if_num_tether)
+ {
+ IPACMDBG_H("Found tether client at position %d.\n", i);
+ break;
+ }
+ }
+ if(i == IPACM_Wan::ipa_if_num_tether_v6_total)
+ {
+ IPACMDBG_H("Not finding the tether client.\n");
+ free(wandown_data);
+ return IPACM_SUCCESS;
+ }
+ for(j = i+1; j < IPACM_Wan::ipa_if_num_tether_v6_total; j++)
+ {
+ IPACM_Wan::ipa_if_num_tether_v6[j-1] = IPACM_Wan::ipa_if_num_tether_v6[j];
+ }
+ IPACM_Wan::ipa_if_num_tether_v6_total--;
+ IPACMDBG_H("Now the total num of ipa_if_num_tether_v6_total is %d \n", IPACM_Wan::ipa_if_num_tether_v6_total);
+ }
+ evt_data.evt_data = (void *)wandown_data;
+ IPACM_EvtDispatcher::PostEvt(&evt_data);
+ return IPACM_SUCCESS;
+}
+#endif
+
/* construct complete ethernet header */
int IPACM_Wan::handle_sta_header_add_evt()
{
diff --git a/ipacm/src/IPACM_Wlan.cpp b/ipacm/src/IPACM_Wlan.cpp
index 075da13..530e2bf 100644
--- a/ipacm/src/IPACM_Wlan.cpp
+++ b/ipacm/src/IPACM_Wlan.cpp
@@ -189,6 +189,14 @@
}
}
#endif
+
+#ifdef FEATURE_IPA_ANDROID
+ /* set the IPA-client pipe enum */
+ if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == WLAN_IF)
+ {
+ handle_tethering_client(false, IPACM_CLIENT_WLAN);
+ }
+#endif
return;
}
@@ -212,6 +220,7 @@
int wlan_index;
ipacm_ext_prop* ext_prop;
ipacm_event_iface_up* data_wan;
+ ipacm_event_iface_up_tehter* data_wan_tether;
switch (event)
{
@@ -342,7 +351,7 @@
}
#endif
- if (IPACM_Wan::isWanUP())
+ if (IPACM_Wan::isWanUP(ipa_if_num))
{
if(data->iptype == IPA_IP_v4 || data->iptype == IPA_IP_MAX)
{
@@ -359,7 +368,7 @@
}
}
- if(IPACM_Wan::isWanUP_V6())
+ if(IPACM_Wan::isWanUP_V6(ipa_if_num))
{
if((data->iptype == IPA_IP_v6 || data->iptype == IPA_IP_MAX) && num_dft_rt_v6 == 1)
{
@@ -391,7 +400,128 @@
}
}
break;
+#ifdef FEATURE_IPA_ANDROID
+ case IPA_HANDLE_WAN_UP_TETHER:
+ IPACMDBG_H("Received IPA_HANDLE_WAN_UP_TETHER event\n");
+ data_wan_tether = (ipacm_event_iface_up_tehter*)param;
+ if(data_wan_tether == NULL)
+ {
+ IPACMERR("No event data is found.\n");
+ return;
+ }
+ IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d\n", data_wan_tether->is_sta,
+ data_wan_tether->if_index_tether);
+ if (iface_ipa_index_query(data_wan_tether->if_index_tether) == ipa_if_num)
+ {
+ if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
+ {
+ if(data_wan_tether->is_sta == false)
+ {
+ ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
+ IPACM_Lan::handle_wan_up_ex(ext_prop, IPA_IP_v4, 0);
+ }
+ else
+ {
+ IPACM_Lan::handle_wan_up(IPA_IP_v4);
+ }
+ }
+ }
+ break;
+
+ case IPA_HANDLE_WAN_UP_V6_TETHER:
+ IPACMDBG_H("Received IPA_HANDLE_WAN_UP_V6_TETHER event\n");
+
+ data_wan_tether = (ipacm_event_iface_up_tehter*)param;
+ if(data_wan_tether == NULL)
+ {
+ IPACMERR("No event data is found.\n");
+ return;
+ }
+ IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d\n", data_wan_tether->is_sta,
+ data_wan_tether->if_index_tether);
+ if (iface_ipa_index_query(data_wan_tether->if_index_tether) == ipa_if_num)
+ {
+ if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
+ {
+ if(wlan_ap_index == 0) //install ipv6 prefix rule only once
+ {
+ install_ipv6_prefix_flt_rule(data_wan_tether->ipv6_prefix);
+ }
+ if(data_wan_tether->is_sta == false)
+ {
+ ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
+ IPACM_Lan::handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
+ }
+ else
+ {
+ IPACM_Lan::handle_wan_up(IPA_IP_v6);
+ }
+ }
+ }
+ break;
+
+ case IPA_HANDLE_WAN_DOWN_TETHER:
+ IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_TETHER event\n");
+ data_wan_tether = (ipacm_event_iface_up_tehter*)param;
+ if(data_wan_tether == NULL)
+ {
+ IPACMERR("No event data is found.\n");
+ return;
+ }
+ IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d, itself %d\n", data_wan_tether->is_sta,
+ iface_ipa_index_query(data_wan_tether->if_index_tether),
+ ipa_if_num);
+ if (iface_ipa_index_query(data_wan_tether->if_index_tether) == ipa_if_num)
+ {
+ if(data_wan_tether->is_sta == false && wlan_ap_index > 0)
+ {
+ IPACMDBG_H("This is not the first AP instance and not STA mode, ignore WAN_DOWN event.\n");
+ return;
+ }
+ if (rx_prop != NULL)
+ {
+ if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
+ {
+ handle_wan_down(data_wan_tether->is_sta);
+ }
+ }
+ }
+ break;
+
+ case IPA_HANDLE_WAN_DOWN_V6_TETHER:
+ IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_V6_TETHER event\n");
+ data_wan_tether = (ipacm_event_iface_up_tehter*)param;
+ if(data_wan_tether == NULL)
+ {
+ IPACMERR("No event data is found.\n");
+ return;
+ }
+ IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d, itself %d\n", data_wan_tether->is_sta,
+ iface_ipa_index_query(data_wan_tether->if_index_tether),
+ ipa_if_num);
+ if (iface_ipa_index_query(data_wan_tether->if_index_tether) == ipa_if_num)
+ {
+ /* clean up v6 RT rules*/
+ IPACMDBG_H("Received IPA_WAN_V6_DOWN in WLAN-instance and need clean up client IPv6 address \n");
+ /* reset wifi-client ipv6 rt-rules */
+ handle_wlan_client_reset_rt(IPA_IP_v6);
+
+ if(data_wan_tether->is_sta == false && wlan_ap_index > 0)
+ {
+ IPACMDBG_H("This is not the first AP instance and not STA mode, ignore WAN_DOWN event.\n");
+ return;
+ }
+ if (rx_prop != NULL)
+ {
+ if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
+ {
+ handle_wan_down_v6(data_wan_tether->is_sta);
+ }
+ }
+ }
+ break;
+#else
case IPA_HANDLE_WAN_UP:
IPACMDBG_H("Received IPA_HANDLE_WAN_UP event\n");
@@ -493,6 +623,7 @@
}
}
break;
+#endif
case IPA_WLAN_CLIENT_ADD_EVENT_EX:
{
@@ -873,7 +1004,7 @@
case IPA_TETHERING_STATS_UPDATE_EVENT:
{
IPACMDBG_H("Received IPA_TETHERING_STATS_UPDATE_EVENT event.\n");
- if (IPACM_Wan::isWanUP() || IPACM_Wan::isWanUP_V6())
+ if (IPACM_Wan::isWanUP(ipa_if_num) || IPACM_Wan::isWanUP_V6(ipa_if_num))
{
if(IPACM_Wan::backhaul_is_sta_mode == false) /* LTE */
{
@@ -2337,13 +2468,13 @@
#endif
/* delete wan filter rule */
- if (IPACM_Wan::isWanUP() && rx_prop != NULL)
+ if (IPACM_Wan::isWanUP(ipa_if_num) && rx_prop != NULL)
{
IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_is_sta_mode);
IPACM_Lan::handle_wan_down(IPACM_Wan::backhaul_is_sta_mode);
}
- if (IPACM_Wan::isWanUP_V6() && rx_prop != NULL)
+ if (IPACM_Wan::isWanUP_V6(ipa_if_num) && rx_prop != NULL)
{
IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_is_sta_mode);
IPACM_Lan::handle_wan_down_v6(IPACM_Wan::backhaul_is_sta_mode);
@@ -2631,6 +2762,8 @@
IPACMERR(" can't Delete IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet);
}
}
+ /* reset the IPA-client pipe enum */
+ handle_tethering_client(true, IPACM_CLIENT_WLAN);
#endif /* defined(FEATURE_IPA_ANDROID)*/
fail: