Disable Stateful SNAT when the related parameter is set to false.

Change-Id: I93cda2325ed27f773002d073ce30f9b4b234aa91
(cherry picked from commit f81088c2ce9bf126a7e7ff32ba85c048c4cda551)
diff --git a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtRouterEvent.java b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtRouterEvent.java
index 4b8ef56..ccd927d 100644
--- a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtRouterEvent.java
+++ b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtRouterEvent.java
@@ -221,7 +221,11 @@
         /**
          * Signified that the gateway node changed for this router.
          */
-        KUBEVIRT_GATEWAY_NODE_CHANGED
+        KUBEVIRT_GATEWAY_NODE_CHANGED,
+        /**
+         * Signified that the snat status disabled for this router.
+         */
+        KUBEVIRT_SNAT_STATUS_DISABLED
     }
 
     /**
diff --git a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/DistributedKubevirtRouterStore.java b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/DistributedKubevirtRouterStore.java
index 87de35e..626d2eb 100644
--- a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/DistributedKubevirtRouterStore.java
+++ b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/DistributedKubevirtRouterStore.java
@@ -67,6 +67,7 @@
 import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_ROUTER_INTERNAL_NETWORKS_DETACHED;
 import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_ROUTER_REMOVED;
 import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_ROUTER_UPDATED;
+import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_SNAT_STATUS_DISABLED;
 import static org.slf4j.LoggerFactory.getLogger;
 
 /**
@@ -324,6 +325,11 @@
                         KUBEVIRT_GATEWAY_NODE_CHANGED,
                         router, oldValue.electedGateway()));
             }
+
+            if (oldValue.enableSnat() && !newValue.enableSnat()) {
+                notifyDelegate(new KubevirtRouterEvent(
+                        KUBEVIRT_SNAT_STATUS_DISABLED, router));
+            }
         }
     }
 
diff --git a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtRoutingArpHandler.java b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtRoutingArpHandler.java
index fd8cb4a..11598a2 100644
--- a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtRoutingArpHandler.java
+++ b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtRoutingArpHandler.java
@@ -234,8 +234,9 @@
                 case KUBEVIRT_ROUTER_EXTERNAL_NETWORK_ATTACHED:
                     eventExecutor.execute(() -> processRouterExternalNetAttachedOrGwAttached(event.subject()));
                     break;
+                case KUBEVIRT_ROUTER_REMOVED:
                 case KUBEVIRT_ROUTER_EXTERNAL_NETWORK_DETACHED:
-                    eventExecutor.execute(() -> processRouterExternalNetDetached(event.subject(),
+                    eventExecutor.execute(() -> processRouterRemovedOrExternalNetDetached(event.subject(),
                             event.externalIp(), event.externalPeerRouterIp()));
                     break;
                 case KUBEVIRT_GATEWAY_NODE_DETACHED:
@@ -272,8 +273,8 @@
             }
         }
 
-        private void processRouterExternalNetDetached(KubevirtRouter router, String routerSnatIp,
-                                                      String peerRouterIp) {
+        private void processRouterRemovedOrExternalNetDetached(KubevirtRouter router, String routerSnatIp,
+                                                               String peerRouterIp) {
             if (!isRelevantHelper()) {
                 return;
             }
diff --git a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtRoutingSnatHandler.java b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtRoutingSnatHandler.java
index c341037..8323f98 100644
--- a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtRoutingSnatHandler.java
+++ b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtRoutingSnatHandler.java
@@ -173,11 +173,17 @@
     }
 
     private void initGatewayNodeSnatForRouter(KubevirtRouter router, boolean install) {
-        KubevirtNode electedGw = gatewayNodeForSpecifiedRouter(kubevirtNodeService, router);
+        if (router.electedGateway() == null) {
+            log.warn("Fail to initialize gateway node snat for router {} " +
+                    "because there's no gateway assigned to it", router.name());
+            return;
+        }
+
+        KubevirtNode electedGw = kubevirtNodeService.node(router.electedGateway());
 
         if (electedGw == null) {
             log.warn("Fail to initialize gateway node snat for router {} " +
-                    "there's no gateway assigned to it", router.name());
+                    "because there's no gateway assigned to it", router.name());
             return;
         }
 
@@ -185,7 +191,7 @@
 
         if (routerSnatIp == null) {
             log.warn("Fail to initialize gateway node snat for router {} " +
-                    "there's no gateway snat ip assigned to it", router.name());
+                    "because there's no gateway snat ip assigned to it", router.name());
             return;
         }
 
@@ -425,6 +431,7 @@
                 case KUBEVIRT_ROUTER_CREATED:
                     eventExecutor.execute(() -> processRouterCreation(event.subject()));
                     break;
+                case KUBEVIRT_SNAT_STATUS_DISABLED:
                 case KUBEVIRT_ROUTER_REMOVED:
                     eventExecutor.execute(() -> processRouterDeletion(event.subject()));
                     break;
@@ -544,6 +551,10 @@
                 return;
             }
 
+            if (!router.enableSnat()) {
+                return;
+            }
+
             router.internal()
                     .stream()
                     .filter(networkId -> kubevirtNetworkService.network(networkId) != null)
@@ -570,6 +581,10 @@
                 return;
             }
 
+            if (!router.enableSnat()) {
+                return;
+            }
+
             router.internal()
                     .stream()
                     .filter(networkId -> kubevirtNetworkService.network(networkId) != null)
@@ -598,6 +613,10 @@
                 return;
             }
 
+            if (!router.enableSnat()) {
+                return;
+            }
+
             attachedInternalNetworks.forEach(networkId -> {
                 String routerSnatIp = router.external().keySet().stream().findAny().orElse(null);
                 if (routerSnatIp == null) {
@@ -621,6 +640,10 @@
                 return;
             }
 
+            if (!router.enableSnat()) {
+                return;
+            }
+
             detachedInternalNetworks.forEach(networkId -> {
                 String routerSnatIp = router.external().keySet().stream().findAny().orElse(null);
                 if (routerSnatIp == null) {
@@ -646,7 +669,7 @@
             if (!isRelevantHelper()) {
                 return;
             }
-            if (router.enableSnat() && !router.external().isEmpty() && router.peerRouter() != null) {
+            if (!router.external().isEmpty() && router.peerRouter() != null) {
                 initGatewayNodeSnatForRouter(router, false);
             }
         }