Stale 21->snat_group flow for external subnet 61/73061/17
authorxcheara <chetan.arakere@altencalsoftlabs.com>
Sat, 16 Jun 2018 16:16:35 +0000 (21:46 +0530)
committerSam Hague <shague@redhat.com>
Fri, 25 Jan 2019 13:33:17 +0000 (13:33 +0000)
Description:
Its been observed that, even on clean-up on External-network Suite,
few of the stale flows 21->snat_group for external subnet where not
been deleted. As a result, Bundle Resync test-case getting failed
with rersync flag enabled due to these stale flows pointing to an
snat_group with corresponding group missing.

Changes are done to take care of clearing vpn-instance-op-data DS
for external-fixed-ip properly ersutling in triggering
ExternalSubnetVpnInstanceListener
and take care of clearing these stale-flows.

Issue : NETVIRT-1311

Change-Id: I773a2f9935a600b7710796d21d9ce39cf4b9a8c0
Signed-off-by: xcheara <chetan.arakere@altencalsoftlabs.com>
Signed-off-by: shaik <shaik.b@altencalsoftlabs.com>
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/ExternalRoutersListener.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/ExternalSubnetChangeListener.java [new file with mode: 0644]
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/ExternalSubnetVpnInstanceListener.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/NaptSwitchHA.java

index 77a61ed333bf6e8de516ef2e94414b0437412039..c0f2033a4df1d963cd1513d072ec27b0083731ef 100644 (file)
@@ -1134,10 +1134,16 @@ public class ExternalRoutersListener extends AsyncDataTreeChangeListenerBase<Rou
                     //Install the flow table 25->44 If there is no FIP Match on table 25 (PDNAT_TABLE)
                     NatUtil.makePreDnatToSnatTableEntry(mdsalManager, dpnId, NwConstants.INBOUND_NAPT_TABLE, confTx);
                 }
-                String fibExternalIp = NatUtil.validateAndAddNetworkMask(externalIp);
+                String externalVpn = vpnName;
                 Uuid externalSubnetId = NatUtil.getExternalSubnetForRouterExternalIp(externalIp, extRouter);
-                Optional<Subnets> externalSubnet = NatUtil.getOptionalExternalSubnets(dataBroker, externalSubnetId);
-                String externalVpn = externalSubnet.isPresent() ? externalSubnetId.getValue() : vpnName;
+                if (extNwProvType == ProviderTypes.VLAN || extNwProvType == ProviderTypes.FLAT) {
+                    Optional<Subnets> externalSubnet = NatUtil.getOptionalExternalSubnets(dataBroker,
+                            externalSubnetId);
+                    if (externalSubnet.isPresent()) {
+                        externalVpn =  externalSubnetId.getValue();
+                    }
+                }
+                String fibExternalIp = NatUtil.validateAndAddNetworkMask(externalIp);
                 CreateFibEntryInput input = new CreateFibEntryInputBuilder()
                     .setVpnName(externalVpn)
                     .setSourceDpid(dpnId).setIpAddress(fibExternalIp).setServiceId(label)
@@ -2288,13 +2294,13 @@ public class ExternalRoutersListener extends AsyncDataTreeChangeListenerBase<Rou
                 removeFlowInvTx);
     }
 
-    protected void delFibTsAndReverseTraffic(final BigInteger dpnId, long routerId, String extIp,
-                                             final String vpnName, Uuid extNetworkId, long tempLabel,
+    protected void delFibTsAndReverseTraffic(final BigInteger dpnId, String routerName, long routerId, String extIp,
+                                             String vpnName, Uuid extNetworkId, long tempLabel,
                                              String gwMacAddress, boolean switchOver,
                                              TypedReadWriteTransaction<Configuration> removeFlowInvTx)
             throws ExecutionException, InterruptedException {
         LOG.debug("delFibTsAndReverseTraffic : Removing fib entry for externalIp {} in routerId {}", extIp, routerId);
-        String routerName = NatUtil.getRouterName(dataBroker,routerId);
+        //String routerName = NatUtil.getRouterName(dataBroker,routerId);
         if (routerName == null) {
             LOG.error("delFibTsAndReverseTraffic : Could not retrieve Router Name from Router ID {} ", routerId);
             return;
@@ -2317,10 +2323,23 @@ public class ExternalRoutersListener extends AsyncDataTreeChangeListenerBase<Rou
                     extIp, routerId);
             return;
         }
-
         final long label = tempLabel;
         final String externalIp = NatUtil.validateAndAddNetworkMask(extIp);
-        RemoveFibEntryInput input = new RemoveFibEntryInputBuilder().setVpnName(vpnName)
+        if (extNwProvType == ProviderTypes.FLAT || extNwProvType == ProviderTypes.VLAN) {
+            LOG.debug("delFibTsAndReverseTraffic : Using extSubnetId as vpnName for FLAT/VLAN use-cases");
+            Routers extRouter = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
+            Uuid externalSubnetId = NatUtil.getExternalSubnetForRouterExternalIp(externalIp,
+                    extRouter);
+
+            Optional<Subnets> externalSubnet = NatUtil.getOptionalExternalSubnets(dataBroker,
+                    externalSubnetId);
+
+            if (externalSubnet.isPresent()) {
+                vpnName =  externalSubnetId.getValue();
+            }
+        }
+        final String externalVpn = vpnName;
+        RemoveFibEntryInput input = new RemoveFibEntryInputBuilder().setVpnName(externalVpn)
                 .setSourceDpid(dpnId).setIpAddress(externalIp).setServiceId(label)
                 .setIpAddressSource(RemoveFibEntryInput.IpAddressSource.ExternalFixedIP).build();
         ListenableFuture<RpcResult<RemoveFibEntryOutput>> future = fibService.removeFibEntry(input);
@@ -2338,7 +2357,7 @@ public class ExternalRoutersListener extends AsyncDataTreeChangeListenerBase<Rou
                     if (result.isSuccessful()) {
                         NatUtil.removePreDnatToSnatTableEntry(removeFlowInvTx, mdsalManager, dpnId);
                         RemoveVpnLabelInput labelInput = new RemoveVpnLabelInputBuilder()
-                            .setVpnName(vpnName).setIpPrefix(externalIp).build();
+                            .setVpnName(externalVpn).setIpPrefix(externalIp).build();
                         return vpnService.removeVpnLabel(labelInput);
                     } else {
                         String errMsg =
@@ -2361,10 +2380,10 @@ public class ExternalRoutersListener extends AsyncDataTreeChangeListenerBase<Rou
                 public void onSuccess(@Nonnull RpcResult<RemoveVpnLabelOutput> result) {
                     if (result.isSuccessful()) {
                         LOG.debug("delFibTsAndReverseTraffic : Successfully removed the label for the prefix {} "
-                            + "from VPN {}", externalIp, vpnName);
+                            + "from VPN {}", externalIp, externalVpn);
                     } else {
                         LOG.error("delFibTsAndReverseTraffic : Error in removing the label for prefix {} "
-                            + " from VPN {}, {}", externalIp, vpnName, result.getErrors());
+                            + " from VPN {}, {}", externalIp, externalVpn, result.getErrors());
                     }
                 }
             }, MoreExecutors.directExecutor());
diff --git a/natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/ExternalSubnetChangeListener.java b/natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/ExternalSubnetChangeListener.java
new file mode 100644 (file)
index 0000000..5bd1316
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2018 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netvirt.natservice.internal;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
+import org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar;
+import org.opendaylight.genius.mdsalutil.NwConstants;
+import org.opendaylight.netvirt.elanmanager.api.IElanService;
+import org.opendaylight.netvirt.vpnmanager.api.IVpnManager;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalSubnets;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.Subnets;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+public class ExternalSubnetChangeListener extends AsyncDataTreeChangeListenerBase<Subnets,
+    ExternalSubnetChangeListener> {
+    private static final Logger LOG = LoggerFactory.getLogger(ExternalSubnetChangeListener.class);
+    private final DataBroker dataBroker;
+    private final SNATDefaultRouteProgrammer snatDefaultRouteProgrammer;
+
+    @Inject
+    public ExternalSubnetChangeListener(final DataBroker dataBroker,
+                     final SNATDefaultRouteProgrammer snatDefaultRouteProgrammer,
+                     final IElanService elanService, final IVpnManager vpnManager,
+                     DataTreeEventCallbackRegistrar dataTreeEventCallbackRegistrar) {
+        this.dataBroker = dataBroker;
+        this.snatDefaultRouteProgrammer = snatDefaultRouteProgrammer;
+    }
+
+    @Override
+    @PostConstruct
+    public void init() {
+        LOG.info("{} init", getClass().getSimpleName());
+        registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
+    }
+
+    @Override
+    protected InstanceIdentifier<Subnets> getWildCardPath() {
+        return InstanceIdentifier.create(ExternalSubnets.class).child(Subnets.class);
+    }
+
+    @Override
+    protected void remove(InstanceIdentifier<Subnets> key, Subnets subnet) {
+        LOG.info("remove : External Subnet remove mapping method - key:{}. value={}",
+                subnet.key(), subnet);
+        String extSubnetUuid = subnet.getId().getValue();
+        long vpnId = NatUtil.getVpnId(dataBroker, extSubnetUuid);
+        if (vpnId == NatConstants.INVALID_ID) {
+            LOG.error("Vpn Instance not found for External subnet : {}", extSubnetUuid);
+            return;
+        } else {
+            snatDefaultRouteProgrammer.addOrDelDefaultFibRouteToSNATForSubnet(subnet,
+                    subnet.getExternalNetworkId().getValue(), NwConstants.DEL_FLOW, vpnId);
+        }
+    }
+
+    @Override
+    protected void update(InstanceIdentifier<Subnets> key, Subnets orig,
+            Subnets update) {
+    }
+
+    @Override
+    protected void add(InstanceIdentifier<Subnets> key, Subnets subnet) {
+    }
+
+    @Override
+    protected ExternalSubnetChangeListener getDataTreeChangeListener() {
+        return ExternalSubnetChangeListener.this;
+    }
+}
index d72905b2e493cdeb01cf1d95560f69514bc6c50b..20e7b55ae798306da80898094008dd059f933f03 100644 (file)
@@ -109,6 +109,11 @@ public class ExternalSubnetVpnInstanceListener extends AsyncDataTreeChangeListen
     private void invokeSubnetDeletedFromVpn(String externalSubnetId) {
         Uuid externalSubnetUuid = new Uuid(externalSubnetId);
         Subnetmap subnetMap = NatUtil.getSubnetMap(dataBroker, externalSubnetUuid);
+        if (subnetMap == null) {
+            LOG.error("invokeSubnetDeletedFromVpn : Cannot invoke invokeSubnetDeletedFromVpn for subnet-id {} in "
+                    + "vpn-id {} due to this subnet missing in Subnetmap model", externalSubnetUuid, externalSubnetId);
+            return;
+        }
         vpnManager.onSubnetDeletedFromVpn(subnetMap, false);
     }
 
index 7ba4e2446b257bb255e31f4fbd76235953ace298..862df7d867cb160d26e9babf0f70b37252432eb9 100644 (file)
@@ -272,7 +272,7 @@ public class NaptSwitchHA {
             for (Entry<String, Long> entry : externalIpmap.entrySet()) {
                 String externalIp = entry.getKey();
                 Long label = entry.getValue();
-                externalRouterListener.delFibTsAndReverseTraffic(naptSwitch, routerId, externalIp, vpnName,
+                externalRouterListener.delFibTsAndReverseTraffic(naptSwitch, routerName, routerId, externalIp, vpnName,
                     extNetworkId, label, gwMacAddress, true, confTx);
                 LOG.debug("removeSnatFlowsInOldNaptSwitch : Successfully removed fib entries in old naptswitch {} "
                     + "for router {} and externalIps {} label {}", naptSwitch, routerId, externalIp, label);
@@ -996,8 +996,8 @@ public class NaptSwitchHA {
             if (extNwProvType == ProviderTypes.VXLAN) {
                 for (String externalIp : removedExternalIps) {
                     externalRouterListener.clearBgpRoutes(externalIp, vpnName);
-                    externalRouterListener.delFibTsAndReverseTraffic(naptSwitch, routerId, externalIp, vpnName,
-                        networkId, NatConstants.DEFAULT_LABEL_VALUE, gwMacAddress, true, confTx);
+                    externalRouterListener.delFibTsAndReverseTraffic(naptSwitch, routerName, routerId, externalIp,
+                        vpnName, networkId, NatConstants.DEFAULT_LABEL_VALUE, gwMacAddress, true, confTx);
                     LOG.debug("bestEffortDeletion : Successfully removed fib entry for externalIp {} for routerId {} "
                                     + "on NAPT switch {} ", externalIp, routerId, naptSwitch);
                 }
@@ -1018,8 +1018,8 @@ public class NaptSwitchHA {
                         continue;
                     }
                     externalRouterListener.clearBgpRoutes(externalIp, vpnName);
-                    externalRouterListener.delFibTsAndReverseTraffic(naptSwitch, routerId, externalIp, vpnName,
-                        networkId, label, gwMacAddress, true, confTx);
+                    externalRouterListener.delFibTsAndReverseTraffic(naptSwitch, routerName, routerId, externalIp,
+                            vpnName, networkId, label, gwMacAddress, true, confTx);
                     LOG.debug("bestEffortDeletion : Successfully removed fib entries in switch {} for router {} "
                             + "and externalIps {}", naptSwitch, routerId, externalIp);
                 }