IPACM: clean wlan NAT ifaces during modem SSR

Wlan-driver will disconnect/reconnect to IPA after modem
SSR and bootup again where framework already send
add_downstream to IPA and resulted in offload failed.
The workaround is to self delete NAT ifaces for wlan
related instances during SSR and cache the downstream
event before wlan restarts.

Change-Id: I178c418621862b19327f70a077623f14a69a56c6
diff --git a/ipacm/inc/IPACM_Defs.h b/ipacm/inc/IPACM_Defs.h
index 2031fc5..149c03a 100644
--- a/ipacm/inc/IPACM_Defs.h
+++ b/ipacm/inc/IPACM_Defs.h
@@ -173,7 +173,7 @@
 
 	IPA_HANDLE_WAN_UP,                        /* ipacm_event_iface_up  */
 	IPA_HANDLE_WAN_DOWN,                      /* ipacm_event_iface_up  */
-	IPA_HANDLE_WAN_UP_V6,                     /* NULL */
+	IPA_HANDLE_WAN_UP_V6,                     /* ipacm_event_iface_up */
 	IPA_HANDLE_WAN_DOWN_V6,                   /* NULL */
 	IPA_HANDLE_WAN_UP_TETHER,                 /* ipacm_event_iface_up_tehter */
 	IPA_HANDLE_WAN_DOWN_TETHER,               /* ipacm_event_iface_up_tehter */
@@ -186,7 +186,7 @@
 	IPA_ETH_BRIDGE_CLIENT_ADD,                /* ipacm_event_eth_bridge */
 	IPA_ETH_BRIDGE_CLIENT_DEL,                /* ipacm_event_eth_bridge*/
 	IPA_ETH_BRIDGE_WLAN_SCC_MCC_SWITCH,       /* ipacm_event_eth_bridge*/
-	IPA_LAN_DELETE_SELF,                      /* ipacm_event_data_fid */
+	IPA_SSR_NOTICE,						      /* NULL*/
 #ifdef FEATURE_L2TP
 	IPA_ADD_VLAN_IFACE,                       /* ipa_ioc_vlan_iface_info */
 	IPA_DEL_VLAN_IFACE,                       /* ipa_ioc_vlan_iface_info */
@@ -195,6 +195,7 @@
 	IPA_HANDLE_VLAN_CLIENT_INFO,              /* ipacm_event_data_all */
 	IPA_HANDLE_VLAN_IFACE_INFO,               /* ipacm_event_data_all */
 #endif
+	IPA_LAN_DELETE_SELF,                      /* ipacm_event_data_fid */
 	IPACM_EVENT_MAX
 } ipa_cm_event_id;
 
diff --git a/ipacm/src/IPACM_IfaceManager.cpp b/ipacm/src/IPACM_IfaceManager.cpp
index 17f546d..85033a3 100644
--- a/ipacm/src/IPACM_IfaceManager.cpp
+++ b/ipacm/src/IPACM_IfaceManager.cpp
@@ -383,6 +383,7 @@
 #ifdef FEATURE_IPACM_HAL
 				IPACM_EvtDispatcher::registr(IPA_DOWNSTREAM_ADD, wl);
 				IPACM_EvtDispatcher::registr(IPA_DOWNSTREAM_DEL, wl);
+				IPACM_EvtDispatcher::registr(IPA_SSR_NOTICE, wl);
 #endif
 #else
 				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP, wl);
@@ -449,6 +450,9 @@
 #ifndef FEATURE_IPA_ANDROID
 						IPACM_EvtDispatcher::registr(IPA_WLAN_SWITCH_TO_SCC, w);
 						IPACM_EvtDispatcher::registr(IPA_WLAN_SWITCH_TO_MCC, w);
+#ifdef FEATURE_IPACM_HAL
+						IPACM_EvtDispatcher::registr(IPA_SSR_NOTICE, w);
+#endif
 #endif
 					}
 					else
diff --git a/ipacm/src/IPACM_Main.cpp b/ipacm/src/IPACM_Main.cpp
index 1f92bfa..55a3fd5 100644
--- a/ipacm/src/IPACM_Main.cpp
+++ b/ipacm/src/IPACM_Main.cpp
@@ -713,7 +713,10 @@
 				IPACMERR("calling OffloadMng->elrInstance->onOffloadStopped \n");
 				OffloadMng->elrInstance->onOffloadStopped(IpaEventRelay::ERROR);
 			}
-			continue;
+			/* WA to clean up wlan instances during SSR */
+			evt_data.event = IPA_SSR_NOTICE;
+			evt_data.evt_data = NULL;
+			break;
 		case IPA_SSR_AFTER_POWERUP:
 			IPACMDBG_H("Received IPA_SSR_AFTER_POWERUP\n");
 			OffloadMng = IPACM_OffloadManager::GetInstance();
diff --git a/ipacm/src/IPACM_OffloadManager.cpp b/ipacm/src/IPACM_OffloadManager.cpp
index 4b85c6e..b13460a 100644
--- a/ipacm/src/IPACM_OffloadManager.cpp
+++ b/ipacm/src/IPACM_OffloadManager.cpp
@@ -445,8 +445,14 @@
 			if (upstream_v6_up == false) {
 				IPACMDBG_H("IPV6 gateway: %08x:%08x:%08x:%08x \n",
 						gw_addr_v6.v6Addr[0], gw_addr_v6.v6Addr[1], gw_addr_v6.v6Addr[2], gw_addr_v6.v6Addr[3]);
-				post_route_evt(IPA_IP_v6, index, IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT, gw_addr_v6);
-				upstream_v6_up = true;
+				/* check v6-address valid or not */
+				if((gw_addr_v6.v6Addr[0] == 0) && (gw_addr_v6.v6Addr[1] ==0) && (gw_addr_v6.v6Addr[2] == 0) && (gw_addr_v6.v6Addr[3] == 0))
+				{
+					IPACMDBG_H("Invliad ipv6-address, ignored v6-setupstream\n");
+				} else {
+					post_route_evt(IPA_IP_v6, index, IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT, gw_addr_v6);
+					upstream_v6_up = true;
+				}
 			} else {
 				IPACMDBG_H("already setupstream iface(%s) ipv6 previously\n", upstream_name);
 			}
@@ -480,8 +486,14 @@
 			if (upstream_v6_up == false) {
 				IPACMDBG_H("IPV6 gateway: %08x:%08x:%08x:%08x \n",
 						gw_addr_v6.v6Addr[0], gw_addr_v6.v6Addr[1], gw_addr_v6.v6Addr[2], gw_addr_v6.v6Addr[3]);
-				post_route_evt(IPA_IP_v6, index, IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT, gw_addr_v6);
-				upstream_v6_up = true;
+				/* check v6-address valid or not */
+				if((gw_addr_v6.v6Addr[0] == 0) && (gw_addr_v6.v6Addr[1] ==0) && (gw_addr_v6.v6Addr[2] == 0) && (gw_addr_v6.v6Addr[3] == 0))
+				{
+					IPACMDBG_H("Invliad ipv6-address, ignored v6-setupstream\n");
+				} else {
+					post_route_evt(IPA_IP_v6, index, IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT, gw_addr_v6);
+					upstream_v6_up = true;
+				}
 			} else {
 				IPACMDBG_H("already setupstream iface(%s) ipv6 previously\n", upstream_name);
 				result = SUCCESS_DUPLICATE_CONFIG;
diff --git a/ipacm/src/IPACM_Wan.cpp b/ipacm/src/IPACM_Wan.cpp
index 6d57c39..cf16c71 100644
--- a/ipacm/src/IPACM_Wan.cpp
+++ b/ipacm/src/IPACM_Wan.cpp
@@ -1254,7 +1254,16 @@
 				}
 			}
 			break;
-
+#ifdef FEATURE_IPACM_HAL
+		/* WA for WLAN to clean up NAT instance during SSR */
+		case IPA_SSR_NOTICE: //sky
+			IPACMDBG_H("Received IPA_SSR_NOTICE event.\n");
+			if(m_is_sta_mode == WLAN_WAN)
+			{
+				IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface
+			}
+		break;
+#endif
 	default:
 		break;
 	}
diff --git a/ipacm/src/IPACM_Wlan.cpp b/ipacm/src/IPACM_Wlan.cpp
index 14fe0b7..ec93233 100644
--- a/ipacm/src/IPACM_Wlan.cpp
+++ b/ipacm/src/IPACM_Wlan.cpp
@@ -910,6 +910,15 @@
 		}
 	}
 	break;
+#ifdef FEATURE_IPACM_HAL
+	/* WA for WLAN to clean up NAT instance during SSR */
+	case IPA_SSR_NOTICE:
+	{
+		IPACMDBG_H("Received IPA_SSR_NOTICE event.\n");
+		IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface
+	}
+	break;
+#endif
 	default:
 		break;
 	}