IPACM: fix ipv6 rules issue for usb/wlan client
When switching LTE+AP to AP+STA mode or LTE+AP to
cradle+AP mode, the ipv6 address of clients are
renewed however IPACM failed to clean up those old
ipv6 routing rules for clients. The fix is to
clean up old ipv6 routing rules when v6 wan down.
Change-Id: I594cd92da893aa46b289a575cb19ef15aefa79d4
diff --git a/ipacm/inc/IPACM_Lan.h b/ipacm/inc/IPACM_Lan.h
index 92475cb..1f561fa 100644
--- a/ipacm/inc/IPACM_Lan.h
+++ b/ipacm/inc/IPACM_Lan.h
@@ -324,7 +324,11 @@
/*handle lan iface down event*/
int handle_down_evt();
- void post_lan2lan_client_disconnect_msg();
+ /*handle lan2lan internal mesg posting*/
+ int post_lan2lan_client_disconnect_msg(ipa_ip_type iptype);
+
+ /*handle reset usb-client rt-rules */
+ int handle_lan_client_reset_rt(ipa_ip_type iptype);
};
#endif /* IPACM_LAN_H */
diff --git a/ipacm/inc/IPACM_Wlan.h b/ipacm/inc/IPACM_Wlan.h
index 631713a..1142772 100644
--- a/ipacm/inc/IPACM_Wlan.h
+++ b/ipacm/inc/IPACM_Wlan.h
@@ -214,7 +214,7 @@
int handle_wlan_client_init_ex(ipacm_event_data_wlan_ex *data);
/*handle lan2lan internal mesg posting*/
- int handle_lan2lan_msg_post(uint8_t *mac_addr, ipa_cm_event_id event);
+ int handle_lan2lan_msg_post(uint8_t *mac_addr, ipa_cm_event_id event, ipa_ip_type iptype);
/*handle wifi client */
int handle_wlan_client_ipaddr(ipacm_event_data_all *data);
@@ -253,7 +253,11 @@
/* install UL filter rule from Q6 */
virtual int handle_uplink_filter_rule(ipacm_ext_prop* prop, ipa_ip_type iptype);
+ /* install TCP control filter rules */
virtual void install_tcp_ctl_flt_rule(ipa_ip_type iptype);
+
+ /*handle reset wifi-client rt-rules */
+ int handle_wlan_client_reset_rt(ipa_ip_type iptype);
};
diff --git a/ipacm/src/IPACM_Lan.cpp b/ipacm/src/IPACM_Lan.cpp
index 0dfbac9..1f967ea 100644
--- a/ipacm/src/IPACM_Lan.cpp
+++ b/ipacm/src/IPACM_Lan.cpp
@@ -377,6 +377,11 @@
IPACMERR("No event data is found.\n");
return;
}
+ /* clean up v6 RT rules*/
+ IPACMDBG("Received IPA_WAN_V6_DOWN 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);
+
IPACMDBG("Backhaul is sta mode?%d\n", data_wan->is_sta);
handle_wan_down_v6(data_wan->is_sta);
break;
@@ -1833,7 +1838,8 @@
}
/* posting ip to lan2lan module to delete RT/FILTER rules*/
- post_lan2lan_client_disconnect_msg();
+ post_lan2lan_client_disconnect_msg(IPA_IP_v4);
+ post_lan2lan_client_disconnect_msg(IPA_IP_v6);
/* Delete private subnet*/
#ifdef FEATURE_IPA_ANDROID
@@ -3115,7 +3121,47 @@
IPACM_EvtDispatcher::PostEvt(&evt);
}
-void IPACM_Lan::post_lan2lan_client_disconnect_msg()
+/*handle reset usb-client rt-rules */
+int IPACM_Lan::handle_lan_client_reset_rt(ipa_ip_type iptype)
+{
+ int i, res = IPACM_SUCCESS;
+
+ /* clean eth-client routing rules */
+ IPACMDBG("left %d eth clients need to be deleted \n ", num_eth_client);
+ for (i = 0; i < num_eth_client; i++)
+ {
+ res = delete_eth_rtrules(i, iptype);
+ if (res != IPACM_SUCCESS)
+ {
+ IPACMERR("Failed to delete old iptype(%d) rules.\n", iptype);
+ return res;
+ }
+ } /* end of for loop */
+
+ /* Pass info to LAN2LAN module */
+ res = post_lan2lan_client_disconnect_msg(iptype);
+ if (res != IPACM_SUCCESS)
+ {
+ IPACMERR("Failed to posting delete old iptype(%d) address.\n", iptype);
+ return res;
+ }
+ /* Reset ip-address */
+ for (i = 0; i < num_eth_client; i++)
+ {
+ if(iptype == IPA_IP_v4)
+ {
+ get_client_memptr(eth_client, i)->ipv4_set = false;
+ }
+ else
+ {
+ get_client_memptr(eth_client, i)->ipv6_set = 0;
+ }
+ } /* end of for loop */
+ return res;
+}
+
+/*handle lan2lan internal mesg posting*/
+int IPACM_Lan::post_lan2lan_client_disconnect_msg(ipa_ip_type iptype)
{
int i, j;
ipacm_cmd_q_data evt_data;
@@ -3123,13 +3169,14 @@
for (i = 0; i < num_eth_client; i++)
{
- if(get_client_memptr(eth_client, i)->ipv4_set == true)
+ if((get_client_memptr(eth_client, i)->ipv4_set == true)
+ && (iptype == IPA_IP_v4))
{
lan_client = (ipacm_event_lan_client*)malloc(sizeof(ipacm_event_lan_client));
if(lan_client == NULL)
{
IPACMERR("Failed to allocate memory.\n");
- return;
+ return IPACM_FAILURE;
}
memset(lan_client, 0, sizeof(ipacm_event_lan_client));
lan_client->iptype = IPA_IP_v4;
@@ -3144,31 +3191,35 @@
IPACM_EvtDispatcher::PostEvt(&evt_data);
}
- for (j = 0; j < get_client_memptr(eth_client, i)->ipv6_set; j++)
+ if((get_client_memptr(eth_client, i)->ipv6_set > 0)
+ && (iptype == IPA_IP_v6))
{
- lan_client = (ipacm_event_lan_client*)malloc(sizeof(ipacm_event_lan_client));
- if(lan_client == NULL)
+ for (j = 0; j < get_client_memptr(eth_client, i)->ipv6_set; j++)
{
- IPACMERR("Failed to allocate memory.\n");
- return;
+ lan_client = (ipacm_event_lan_client*)malloc(sizeof(ipacm_event_lan_client));
+ if(lan_client == NULL)
+ {
+ IPACMERR("Failed to allocate memory.\n");
+ return IPACM_FAILURE;
+ }
+ memset(lan_client, 0, sizeof(ipacm_event_lan_client));
+ lan_client->iptype = IPA_IP_v6;
+ lan_client->ipv6_addr[0] = get_client_memptr(eth_client, i)->v6_addr[j][0];
+ lan_client->ipv6_addr[0] = get_client_memptr(eth_client, i)->v6_addr[j][0];
+ lan_client->ipv6_addr[0] = get_client_memptr(eth_client, i)->v6_addr[j][0];
+ lan_client->ipv6_addr[0] = get_client_memptr(eth_client, i)->v6_addr[j][0];
+ lan_client->p_iface = this;
+
+ memset(&evt_data, 0, sizeof(ipacm_cmd_q_data));
+ evt_data.evt_data = (void*)lan_client;
+ evt_data.event = IPA_LAN_CLIENT_DISCONNECT;
+
+ IPACMDBG("Posting event IPA_LAN_CLIENT_DISCONNECT\n");
+ IPACM_EvtDispatcher::PostEvt(&evt_data);
}
- memset(lan_client, 0, sizeof(ipacm_event_lan_client));
- lan_client->iptype = IPA_IP_v6;
- lan_client->ipv6_addr[0] = get_client_memptr(eth_client, i)->v6_addr[j][0];
- lan_client->ipv6_addr[0] = get_client_memptr(eth_client, i)->v6_addr[j][0];
- lan_client->ipv6_addr[0] = get_client_memptr(eth_client, i)->v6_addr[j][0];
- lan_client->ipv6_addr[0] = get_client_memptr(eth_client, i)->v6_addr[j][0];
- lan_client->p_iface = this;
-
- memset(&evt_data, 0, sizeof(ipacm_cmd_q_data));
- evt_data.evt_data = (void*)lan_client;
- evt_data.event = IPA_LAN_CLIENT_DISCONNECT;
-
- IPACMDBG("Posting event IPA_LAN_CLIENT_DISCONNECT\n");
- IPACM_EvtDispatcher::PostEvt(&evt_data);
}
} /* end of for loop */
- return;
+ return IPACM_SUCCESS;
}
void IPACM_Lan::install_tcp_ctl_flt_rule(ipa_ip_type iptype)
diff --git a/ipacm/src/IPACM_Wlan.cpp b/ipacm/src/IPACM_Wlan.cpp
index e111bfd..f26a900 100644
--- a/ipacm/src/IPACM_Wlan.cpp
+++ b/ipacm/src/IPACM_Wlan.cpp
@@ -364,6 +364,11 @@
IPACMERR("No event data is found.\n");
return;
}
+ /* clean up v6 RT rules*/
+ IPACMDBG("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);
+
IPACMDBG("Backhaul is sta mode?%d\n", data_wan->is_sta);
if(data_wan->is_sta == false && wlan_ap_index > 0)
{
@@ -396,7 +401,8 @@
{
IPACMDBG("Received IPA_WLAN_CLIENT_DEL_EVENT\n");
/* support lan2lan ipa-HW feature*/
- handle_lan2lan_msg_post(data->mac_addr, IPA_LAN_CLIENT_DISCONNECT);
+ handle_lan2lan_msg_post(data->mac_addr, IPA_LAN_CLIENT_DISCONNECT, IPA_IP_v4);
+ handle_lan2lan_msg_post(data->mac_addr, IPA_LAN_CLIENT_DISCONNECT, IPA_IP_v6);
handle_wlan_client_down_evt(data->mac_addr);
}
}
@@ -410,7 +416,8 @@
{
IPACMDBG("Received IPA_WLAN_CLIENT_POWER_SAVE_EVENT\n");
/* support lan2lan ipa-HW feature*/
- handle_lan2lan_msg_post(data->mac_addr, IPA_LAN_CLIENT_POWER_SAVE);
+ handle_lan2lan_msg_post(data->mac_addr, IPA_LAN_CLIENT_POWER_SAVE, IPA_IP_v4);
+ handle_lan2lan_msg_post(data->mac_addr, IPA_LAN_CLIENT_POWER_SAVE, IPA_IP_v6);
handle_wlan_client_pwrsave(data->mac_addr);
}
}
@@ -424,7 +431,8 @@
{
IPACMDBG("Received IPA_WLAN_CLIENT_RECOVER_EVENT\n");
/* support lan2lan ipa-HW feature*/
- handle_lan2lan_msg_post(data->mac_addr, IPA_LAN_CLIENT_POWER_RECOVER);
+ handle_lan2lan_msg_post(data->mac_addr, IPA_LAN_CLIENT_POWER_RECOVER, IPA_IP_v4);
+ handle_lan2lan_msg_post(data->mac_addr, IPA_LAN_CLIENT_POWER_RECOVER, IPA_IP_v6);
wlan_index = get_wlan_client_index(data->mac_addr);
if ((wlan_index != IPACM_INVALID_INDEX) &&
@@ -1978,7 +1986,8 @@
IPACMDBG("Delete %d client header\n", num_wifi_client);
- handle_lan2lan_msg_post(get_client_memptr(wlan_client, i)->mac, IPA_LAN_CLIENT_DISCONNECT);
+ handle_lan2lan_msg_post(get_client_memptr(wlan_client, i)->mac, IPA_LAN_CLIENT_DISCONNECT, IPA_IP_v4);
+ handle_lan2lan_msg_post(get_client_memptr(wlan_client, i)->mac, IPA_LAN_CLIENT_DISCONNECT, IPA_IP_v6);
if(get_client_memptr(wlan_client, i)->ipv4_header_set == true)
{
@@ -2046,8 +2055,45 @@
return res;
}
+/*handle reset wifi-client rt-rules */
+int IPACM_Wlan::handle_wlan_client_reset_rt(ipa_ip_type iptype)
+{
+ int i, res = IPACM_SUCCESS;
+
+ /* clean wifi-client routing rules */
+ IPACMDBG("left %d wifi clients to reset ip-type(%d) rules \n ", num_wifi_client, iptype);
+
+ for (i = 0; i < num_wifi_client; i++)
+ {
+ /* Reset RT rules */
+ res = delete_default_qos_rtrules(i, iptype);
+ if (res != IPACM_SUCCESS)
+ {
+ IPACMERR("Failed to delete old iptype(%d) rules.\n", iptype);
+ return res;
+ }
+ /* Pass info to LAN2LAN module */
+ res = handle_lan2lan_msg_post(get_client_memptr(wlan_client, i)->mac, IPA_LAN_CLIENT_DISCONNECT, iptype);
+ if (res != IPACM_SUCCESS)
+ {
+ IPACMERR("Failed to posting delete old iptype(%d) address.\n", iptype);
+ return res;
+ }
+ /* Reset ip-address */
+ if(iptype == IPA_IP_v4)
+ {
+ get_client_memptr(wlan_client, i)->ipv4_set = false;
+ }
+ else
+ {
+ get_client_memptr(wlan_client, i)->ipv6_set = 0;
+ }
+ } /* end of for loop */
+ return res;
+}
+
/*handle lan2lan internal mesg posting*/
-int IPACM_Wlan::handle_lan2lan_msg_post(uint8_t *mac_addr, ipa_cm_event_id event)
+int IPACM_Wlan::handle_lan2lan_msg_post(uint8_t *mac_addr, ipa_cm_event_id event,ipa_ip_type iptype)
{
int client_index;
client_index = get_wlan_client_index(mac_addr);
@@ -2059,7 +2105,8 @@
ipacm_event_lan_client* lan_client;
ipacm_cmd_q_data evt_data;
- if(get_client_memptr(wlan_client, client_index)->ipv4_set == true) /* handle ipv4 case*/
+ if((get_client_memptr(wlan_client, client_index)->ipv4_set == true)
+ && (iptype == IPA_IP_v4)) /* handle ipv4 case*/
{
if(ip_type != IPA_IP_v4 && ip_type != IPA_IP_MAX)
{
@@ -2087,7 +2134,8 @@
IPACM_EvtDispatcher::PostEvt(&evt_data);
}
- if(get_client_memptr(wlan_client, client_index)->ipv6_set > 0) /* handle v6 case: may be multiple v6 addr */
+ if((get_client_memptr(wlan_client, client_index)->ipv6_set > 0)
+ && (iptype == IPA_IP_v6)) /* handle v6 case: may be multiple v6 addr */
{
if(ip_type != IPA_IP_v6 && ip_type != IPA_IP_MAX)
{
@@ -2631,6 +2679,7 @@
return;
}
+/* install TCP control filter rules */
void IPACM_Wlan::install_tcp_ctl_flt_rule(ipa_ip_type iptype)
{
if (rx_prop == NULL)