msm: ipacm: Added unordered addDownstream/removeDownstream handling
addDownstream and removeDownstream events can arrive in any order
during SSC mode 3 and hence these should be handled irrespective
of the order of their arrival
Change-Id: Iff28f9ca0d75fefa49e1f2fb9c8a9a9cb4a58f5d
Acked-by: Abhishek Raghuvanshi <araghuva@qti.qualcomm.com>
Signed-off-by: Chaitanya Pratapa <quic_cpratapa@quicinc.com>
diff --git a/ipacm/src/IPACM_Lan.cpp b/ipacm/src/IPACM_Lan.cpp
index 4201624..88d38bc 100644
--- a/ipacm/src/IPACM_Lan.cpp
+++ b/ipacm/src/IPACM_Lan.cpp
@@ -773,6 +773,32 @@
{
IPACMDBG_H("Received IPA_DOWNSTREAM_ADD event.\n");
+ /* Delete existing downstream if it exists */
+ if (is_downstream_set[data->prefix.iptype] == true)
+ {
+ if (ipv6_prefix[0] != data->prefix.v6Addr[0] ||
+ ipv6_prefix[1] != data->prefix.v6Addr[1])
+ {
+ IPACMDBG_H("Del existing downstream for IP iptype %d.\n", data->prefix.iptype);
+ is_downstream_set[data->prefix.iptype] = false;
+ store_downstream_state(false, data->prefix.iptype);
+ if (is_upstream_set[data->prefix.iptype] == true)
+ {
+ IPACMDBG_H("Upstream was set before, deleting UL rules.\n");
+ if (data->prefix.iptype == IPA_IP_v4)
+ {
+ /* LTE STA */
+ handle_wan_down(IPACM_Wan::backhaul_mode);
+ } else {
+ handle_lan_client_reset_rt(IPA_IP_v6);
+
+ /* LTE STA */
+ handle_wan_down_v6(IPACM_Wan::backhaul_mode);
+ }
+ }
+ }
+ }
+
if (data->prefix.iptype < IPA_IP_MAX && is_downstream_set[data->prefix.iptype] == false)
{
IPACMDBG_H("Add downstream for IP iptype %d\n", data->prefix.iptype);
@@ -829,18 +855,23 @@
IPACMDBG_H("Received IPA_DOWNSTREAM_DEL event.\n");
if (is_downstream_set[data->prefix.iptype] == true)
{
- IPACMDBG_H("Del downstream for IP iptype %d.\n", data->prefix.iptype);
- is_downstream_set[data->prefix.iptype] = false;
- store_downstream_state(false, data->prefix.iptype);
- if (is_upstream_set[data->prefix.iptype] == true)
+ /* Handle downstream del event only when the prefix matches */
+ if (ipv6_prefix[0] == data->prefix.v6Addr[0] &&
+ ipv6_prefix[1] == data->prefix.v6Addr[1])
{
- IPACMDBG_H("Upstream was set before, deleting UL rules.\n");
- if (data->prefix.iptype == IPA_IP_v4)
+ IPACMDBG_H("Del downstream for IP iptype %d.\n", data->prefix.iptype);
+ is_downstream_set[data->prefix.iptype] = false;
+ store_downstream_state(false, data->prefix.iptype);
+ if (is_upstream_set[data->prefix.iptype] == true)
{
- handle_wan_down(IPACM_Wan::backhaul_mode); /* LTE STA */
- } else {
- handle_lan_client_reset_rt(IPA_IP_v6);
- handle_wan_down_v6(IPACM_Wan::backhaul_mode); /* LTE STA */
+ IPACMDBG_H("Upstream was set before, deleting UL rules.\n");
+ if (data->prefix.iptype == IPA_IP_v4)
+ {
+ handle_wan_down(IPACM_Wan::backhaul_mode); /* LTE STA */
+ } else {
+ handle_lan_client_reset_rt(IPA_IP_v6);
+ handle_wan_down_v6(IPACM_Wan::backhaul_mode); /* LTE STA */
+ }
}
}
}
diff --git a/ipacm/src/IPACM_Wlan.cpp b/ipacm/src/IPACM_Wlan.cpp
index 58bbeee..c596256 100644
--- a/ipacm/src/IPACM_Wlan.cpp
+++ b/ipacm/src/IPACM_Wlan.cpp
@@ -562,6 +562,33 @@
if(ipa_interface_index == ipa_if_num)
{
IPACMDBG_H("Received IPA_DOWNSTREAM_ADD event.\n");
+
+ /* Delete any existing downstream before adding a new one*/
+ if(is_downstream_set[data->prefix.iptype] == true)
+ {
+ if (ipv6_prefix[0] != data->prefix.v6Addr[0] ||
+ ipv6_prefix[1] != data->prefix.v6Addr[1])
+ {
+ IPACMDBG_H("Del existing downstream for IP iptype %d.\n", data->prefix.iptype);
+ is_downstream_set[data->prefix.iptype] = false;
+ store_downstream_state(false, data->prefix.iptype);
+ if(is_upstream_set[data->prefix.iptype] == true)
+ {
+ IPACMDBG_H("Upstream was set before, deleting UL rules.\n");
+ if (data->prefix.iptype == IPA_IP_v4)
+ {
+ /* LTE STA */
+ handle_wan_down(IPACM_Wan::backhaul_mode);
+ } else {
+ handle_wlan_client_reset_rt(IPA_IP_v6);
+
+ /* LTE STA */
+ handle_wan_down_v6(IPACM_Wan::backhaul_mode);
+ }
+ }
+ }
+ }
+
if(data->prefix.iptype < IPA_IP_MAX && is_downstream_set[data->prefix.iptype] == false)
{
IPACMDBG_H("Add downstream for IP iptype %d.\n", data->prefix.iptype);
@@ -615,18 +642,23 @@
IPACMDBG_H("Received IPA_DOWNSTREAM_DEL event.\n");
if(is_downstream_set[data->prefix.iptype] == true)
{
- IPACMDBG_H("Del downstream for IP iptype %d.\n", data->prefix.iptype);
- is_downstream_set[data->prefix.iptype] = false;
- store_downstream_state(false, data->prefix.iptype);
- if(is_upstream_set[data->prefix.iptype] == true)
+ /* Handle downstream del event only when the prefix matches */
+ if (ipv6_prefix[0] == data->prefix.v6Addr[0] &&
+ ipv6_prefix[1] == data->prefix.v6Addr[1])
{
- IPACMDBG_H("Upstream was set before, deleting UL rules.\n");
- if (data->prefix.iptype == IPA_IP_v4)
+ IPACMDBG_H("Del downstream for IP iptype %d.\n", data->prefix.iptype);
+ is_downstream_set[data->prefix.iptype] = false;
+ store_downstream_state(false, data->prefix.iptype);
+ if(is_upstream_set[data->prefix.iptype] == true)
{
- handle_wan_down(IPACM_Wan::backhaul_mode); /* LTE STA */
- } else {
- handle_wlan_client_reset_rt(IPA_IP_v6);
- handle_wan_down_v6(IPACM_Wan::backhaul_mode); /* LTE STA */
+ IPACMDBG_H("Upstream was set before, deleting UL rules.\n");
+ if (data->prefix.iptype == IPA_IP_v4)
+ {
+ handle_wan_down(IPACM_Wan::backhaul_mode); /* LTE STA */
+ } else {
+ handle_wlan_client_reset_rt(IPA_IP_v6);
+ handle_wan_down_v6(IPACM_Wan::backhaul_mode); /* LTE STA */
+ }
}
}
}