Bug 8165 - Learnt IP route does not reappear on DC-GW after OVSRestart 08/54408/10
authoreupakir <kiran.n.upadhyaya@ericsson.com>
Thu, 6 Apr 2017 08:47:56 +0000 (14:17 +0530)
committerSam Hague <shague@redhat.com>
Mon, 10 Apr 2017 03:16:25 +0000 (03:16 +0000)
On OVS Restart, a learnt IP will have to be deleted by Liveness
Monitor, and then re-learnt once the OVS comes up.
But this IP was not learned again.

Cyclic events were getting spawned while processing removal of
Learnt IPs.  This was causing deletion of re-learnt IPs.

Change-Id: I17b87fef05de8d3eb51f2a4720df98ff647e8937
Signed-off-by: eupakir <kiran.n.upadhyaya@ericsson.com>
Signed-off-by: Vivekanandan Narasimhan <n.vivekanandan@ericsson.com>
vpnservice/vpnmanager/vpnmanager-api/src/main/yang/odl-l3vpn.yang
vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/ArpMonitorEventListener.java
vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/ArpMonitorStopTask.java
vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/ArpMonitoringHandler.java
vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/ArpNotificationHandler.java
vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/MacEntry.java
vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnUtil.java

index cc4ff8c900a6b5059131f852e14d818f65b6a8bf..cb2908e81677da1b06bbf0f57dd1fd16b8ed02be 100644 (file)
@@ -485,6 +485,7 @@ module odl-l3vpn {
             leaf port-fixedip { type string; }
             leaf port-name { type string; }
             leaf mac-address { type string; }
+            leaf creation-time { type string; }
         }
     }
 
index ddc430f08a982bfb783aa999893fd8703bc46e70..42e1f5728df52cfd9ed1502bcf07f4f71a8b74ea 100644 (file)
@@ -14,6 +14,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.AlivenessMonitorService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.LivenessState;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorEvent;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -41,10 +42,15 @@ public class ArpMonitorEventListener implements AlivenessMonitorListener {
         }
         LivenessState livenessState = notification.getEventData().getMonitorState();
         if (livenessState.equals(LivenessState.Down)) {
-            DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
-            coordinator.enqueueJob(ArpMonitoringHandler.buildJobKey(macEntry.getIpAddress().getHostAddress(),
-                macEntry.getVpnName()),
-                new ArpMonitorStopTask(macEntry, dataBroker, alivenessManager));
+            String vpnName = macEntry.getVpnName();
+            String learntIp = macEntry.getIpAddress().getHostAddress();
+            LearntVpnVipToPort vpnVipToPort = VpnUtil.getLearntVpnVipToPort(dataBroker, vpnName, learntIp);
+            if (vpnVipToPort != null && macEntry.getCreatedTime().equals(vpnVipToPort.getCreationTime())) {
+                DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+                coordinator.enqueueJob(ArpMonitoringHandler.buildJobKey(macEntry.getIpAddress().getHostAddress(),
+                        macEntry.getVpnName()), new ArpMonitorStopTask(macEntry, dataBroker, alivenessManager));
+            }
+
         }
     }
 
index b51946635cae2cbe7905546d4f43aee7fe5ca02d..80b16fbf9ecf08799f85a0b10df299840c7732d1 100644 (file)
@@ -8,16 +8,15 @@
 package org.opendaylight.netvirt.vpnmanager;
 
 import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.ListenableFuture;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
+
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.AlivenessMonitorService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adjacencies;
@@ -44,24 +43,18 @@ public class ArpMonitorStopTask implements Callable<List<ListenableFuture<Void>>
     @Override
     public List<ListenableFuture<Void>> call() throws Exception {
         final List<ListenableFuture<Void>> futures = new ArrayList<>();
-        WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
         java.util.Optional<Long> monitorIdOptional = AlivenessMonitorUtils.getMonitorIdFromInterface(macEntry);
-        monitorIdOptional.ifPresent(aLong -> AlivenessMonitorUtils.stopArpMonitoring(alivenessManager, aLong));
-        removeMipAdjacency(macEntry.getIpAddress().getHostAddress(),
-                macEntry.getVpnName(), macEntry.getInterfaceName(), tx);
-        VpnUtil.removeLearntVpnVipToPort(dataBroker, macEntry.getVpnName(),
-                macEntry.getIpAddress().getHostAddress());
-        CheckedFuture<Void, TransactionCommitFailedException> txFutures = tx.submit();
-        try {
-            txFutures.get();
-        } catch (InterruptedException | ExecutionException e) {
-            LOG.error("Error writing to datastore {}", e);
-        }
-        futures.add(txFutures);
+        monitorIdOptional.ifPresent(monitorId -> {
+            AlivenessMonitorUtils.stopArpMonitoring(alivenessManager, monitorId);
+            removeMipAdjacency(macEntry.getIpAddress().getHostAddress(),
+                    macEntry.getVpnName(), macEntry.getInterfaceName());
+            VpnUtil.removeLearntVpnVipToPort(dataBroker, macEntry.getVpnName(),
+                    macEntry.getIpAddress().getHostAddress());
+        });
         return futures;
     }
 
-    private void removeMipAdjacency(String fixedip, String vpnName, String interfaceName, WriteTransaction tx) {
+    private void removeMipAdjacency(String fixedip, String vpnName, String interfaceName) {
         synchronized (interfaceName.intern()) {
             InstanceIdentifier<VpnInterface> vpnIfId = VpnUtil.getVpnInterfaceIdentifier(interfaceName);
             InstanceIdentifier<Adjacencies> path = vpnIfId.augmentation(Adjacencies.class);
@@ -69,8 +62,15 @@ public class ArpMonitorStopTask implements Callable<List<ListenableFuture<Void>>
             if (adjacencies.isPresent()) {
                 InstanceIdentifier<Adjacency> adid = vpnIfId.augmentation(Adjacencies.class).child(Adjacency.class,
                     new AdjacencyKey(ipToPrefix(fixedip)));
-                tx.delete(LogicalDatastoreType.CONFIGURATION, adid);
-                LOG.info("deleting the adjacencies for vpn {} interface {}", vpnName, interfaceName);
+                try {
+                    SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, adid);
+                } catch (TransactionCommitFailedException e) {
+                    LOG.error("Failed to delete the learned-ip-adjacency for vpn {} interface {} prefix {}",
+                            vpnName, interfaceName, ipToPrefix(fixedip), e);
+                    return;
+                }
+                LOG.info("Successfully deleted the learned-ip-adjacency prefix {} on vpn {} for interface {}",
+                        ipToPrefix(fixedip), vpnName, interfaceName);
             }
         }
     }
index de6c849b06e700de4748860eec78da1c8ec34cca..af0c06a6f68b0cb3884eab72a14085c352cefa74 100644 (file)
@@ -118,8 +118,8 @@ public class ArpMonitoringHandler
                 }
                 MacAddress srcMacAddress = MacAddress.getDefaultInstance(value.getMacAddress());
                 String vpnName =  value.getVpnName();
-                String interfaceName =  value.getPortName();
-                MacEntry macEntry = new MacEntry(vpnName, srcMacAddress, srcInetAddr, interfaceName);
+                MacEntry macEntry = new MacEntry(vpnName, srcMacAddress, srcInetAddr, value.getPortName(),
+                        value.getCreationTime());
                 DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
                 coordinator.enqueueJob(buildJobKey(srcInetAddr.toString(), vpnName),
                         new ArpMonitorStartTask(macEntry, arpMonitorProfileId, dataBroker, alivenessManager,
@@ -139,10 +139,18 @@ public class ArpMonitoringHandler
                     LOG.warn("The mac address received is null for LearntVpnVipToPort {}, ignoring the DTCN", value);
                     return;
                 }
-                MacAddress srcMacAddress = MacAddress.getDefaultInstance(value.getMacAddress());
                 String vpnName =  value.getVpnName();
+                String learntIp = srcInetAddr.getHostAddress();
+                LearntVpnVipToPort vpnVipToPort = VpnUtil.getLearntVpnVipToPort(dataBroker, vpnName, learntIp);
+                if (vpnVipToPort != null && !vpnVipToPort.getCreationTime().equals(value.getCreationTime())) {
+                    LOG.warn("The MIP {} over vpn {} has been learnt again and processed. "
+                            + "Ignoring this remove event.", learntIp, vpnName);
+                    return;
+                }
+                MacAddress srcMacAddress = MacAddress.getDefaultInstance(value.getMacAddress());
                 String interfaceName =  value.getPortName();
-                MacEntry macEntry = new MacEntry(vpnName, srcMacAddress, srcInetAddr, interfaceName);
+                MacEntry macEntry = new MacEntry(vpnName, srcMacAddress, srcInetAddr, interfaceName,
+                        value.getCreationTime());
                 DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
                 coordinator.enqueueJob(buildJobKey(srcInetAddr.toString(), vpnName),
                         new ArpMonitorStopTask(macEntry, dataBroker, alivenessManager));
index fe7f05cd4ee8e0cdf441841f99028a7544d9f4eb..2309a533d4891700473e656bce93566c2d1d25e3 100644 (file)
@@ -287,7 +287,8 @@ public class ArpNotificationHandler implements OdlArputilListener {
                         new VpnInterfaceKey(vpnInterface)).augmentation(Adjacencies.class).child(Adjacency.class,
                         new AdjacencyKey(ip)).build();
                 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, adjacencyIdentifier);
-                LOG.trace("Successfully Deleted Adjacency into VpnInterface {}", vpnInterface);
+                LOG.info("Successfully deleted the learned-ip-adjacency for prefix {} on vpn {} for interface {}",
+                        ip, vpnName, vpnInterface);
             }
         }
     }
index 79a8d5bb68c77b40a6ae5634e4127f6d14c73372..f3456099856945658fca99fceb577e562ffc265c 100644 (file)
@@ -15,13 +15,15 @@ public class MacEntry {
     private MacAddress macAddress;
     private InetAddress ipAddress;
     private String interfaceName;
+    private String createdTime;
 
-    public MacEntry(String vpnName, MacAddress macAddress,
-        InetAddress inetAddress, String interfaceName) {
+    public MacEntry(String vpnName, MacAddress macAddress, InetAddress inetAddress,
+                    String interfaceName, String createdTime) {
         this.vpnName = vpnName;
         this.macAddress = macAddress;
         this.ipAddress = inetAddress;
         this.interfaceName = interfaceName;
+        this.createdTime = createdTime;
     }
 
     public String getVpnName() {
@@ -48,6 +50,10 @@ public class MacEntry {
         return ipAddress;
     }
 
+    public String getCreatedTime() {
+        return  createdTime;
+    }
+
     @Override
     public int hashCode() {
         final int prime = 31;
@@ -63,14 +69,17 @@ public class MacEntry {
             return false;
         } else {
             MacEntry other = (MacEntry) obj;
-            return vpnName.equals(other.vpnName) && macAddress.equals(other.macAddress)
-                && ipAddress.equals(other.ipAddress) && interfaceName.equals(other.interfaceName);
+            return vpnName.equals(other.vpnName)
+                    && macAddress.equals(other.macAddress)
+                    && ipAddress.equals(other.ipAddress)
+                    && interfaceName.equals(other.interfaceName)
+                    && createdTime.equals(other.getCreatedTime());
         }
     }
 
     @Override
     public String toString() {
         return "MacEntry [vpnName=" + vpnName + ", macAddress=" + macAddress + ", ipAddress=" + ipAddress
-            + ", interfaceName=" + interfaceName + "]";
+            + ", interfaceName=" + interfaceName + ", createdTime=" + createdTime + "]";
     }
 }
index 57ccee3d9f6a9812cf0ca9d1f2b7b5057eebddd3..2077b65e82ab5a2ad8b51e3e419d3c70f19490bf 100755 (executable)
@@ -15,8 +15,10 @@ import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 
 import java.math.BigInteger;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Date;
 import java.util.List;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
@@ -1067,8 +1069,9 @@ public class VpnUtil {
             InstanceIdentifier<LearntVpnVipToPort> id = buildLearntVpnVipToPortIdentifier(vpnName, fixedIp);
             LearntVpnVipToPortBuilder builder =
                     new LearntVpnVipToPortBuilder().setKey(new LearntVpnVipToPortKey(fixedIp, vpnName)).setVpnName(
-                            vpnName).setPortFixedip(fixedIp).setPortName(portName).setMacAddress(
-                            macAddress.toLowerCase());
+                            vpnName).setPortFixedip(fixedIp).setPortName(portName)
+                            .setMacAddress(macAddress.toLowerCase())
+                            .setCreationTime(new SimpleDateFormat("MM/dd/yyyy h:mm:ss a").format(new Date()));
             MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, id, builder.build());
             LOG.debug("ARP learned for fixedIp: {}, vpn {}, interface {}, mac {}, isSubnetIp {} added to "
                     + "VpnPortipToPort DS", fixedIp, vpnName, portName, macAddress);