NETVIRT-1520: AlivenessMonitor cache issue 83/78083/7
authorAnil Kumar Gujele <anilkumar.g@altencalsoftlabs.com>
Fri, 23 Nov 2018 09:44:49 +0000 (15:14 +0530)
committerSam Hague <shague@redhat.com>
Fri, 25 Jan 2019 03:22:32 +0000 (03:22 +0000)
Issue:
Say VM with MIP-IP is on DPN connected to Contorller-1, when MIP is
learnt , it populates the cache alivenessCache. When VM migrates to
another DPN, which is connected to say Controller-2, the same
alivenessCache will not have data w.r.t the monitoring session
created by Controller-1.
Hence incase of cleanup , it causes issues in stopping ArpMonitoring.
The cache is simple local cache which doesnt work incase of cluster.

Fix:
Better to read InterfaceMonitorMap directly from datastore so that
monitorId can be retrieved even if MIP moves across DPNs connected to
various controllers in cluster.

Change-Id: I1e4102a7c57bff8376d3d05be8975a6c1ad74233
Signed-off-by: Anil Kumar Gujele <anilkumar.g@altencalsoftlabs.com>
vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/iplearn/AlivenessMonitorUtils.java
vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/iplearn/IpMonitorStopTask.java

index f99da2ccbfa64ca5539c13d23af4c51bdb00d4ad..1a5262cbf704d6dfd6ac21e867c06be9a81e2cff 100644 (file)
@@ -15,8 +15,10 @@ import java.util.concurrent.Future;
 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.arputil.api.ArpConstants;
 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
+import org.opendaylight.genius.mdsalutil.MDSALUtil;
 import org.opendaylight.infrautils.utils.concurrent.JdkFutures;
 import org.opendaylight.netvirt.neutronvpn.interfaces.INeutronVpnManager;
 import org.opendaylight.netvirt.vpnmanager.VpnUtil;
@@ -25,6 +27,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.AlivenessMonitorService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.InterfaceMonitorMap;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorProfileCreateInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorProfileCreateInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorProfileCreateOutput;
@@ -38,6 +41,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorStopInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorStopInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitoringMode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411._interface.monitor.map.InterfaceMonitorEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411._interface.monitor.map.InterfaceMonitorEntryKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.endpoint.endpoint.type.Interface;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.endpoint.endpoint.type.InterfaceBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.monitor.params.DestinationBuilder;
@@ -46,6 +51,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.monitor.profile.create.input.ProfileBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.monitor.start.input.ConfigBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.config.rev161130.VpnConfig;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -239,12 +245,20 @@ public final class AlivenessMonitorUtils {
             .endpoint.endpoint.type.IpAddressBuilder().setIpAddress(ip).build();
     }
 
-    public static java.util.Optional<Long> getMonitorIdFromInterface(MacEntry macEntry) {
-        java.util.Optional<Long> monitorId = alivenessCache.entrySet().parallelStream()
-            .filter(map -> macEntry.equals(map.getValue()))
-            .map(Map.Entry::getKey)
-            .findFirst();
+    public java.util.Optional<Long> getMonitorIdFromInterface(MacEntry macEntry) {
+        String interfaceName = macEntry.getInterfaceName();
+        java.util.Optional<Long> monitorId = java.util.Optional.empty();
+        Optional<InterfaceMonitorEntry> interfaceMonitorEntryOptional = MDSALUtil.read(dataBroker,
+                LogicalDatastoreType.OPERATIONAL, getInterfaceMonitorMapId(interfaceName));
+        if (interfaceMonitorEntryOptional.isPresent()) {
+            return java.util.Optional.of(interfaceMonitorEntryOptional.get().getMonitorIds().get(0));
+        }
         return monitorId;
     }
 
+    private InstanceIdentifier<InterfaceMonitorEntry> getInterfaceMonitorMapId(String interfaceName) {
+        return InstanceIdentifier.builder(InterfaceMonitorMap.class)
+                .child(InterfaceMonitorEntry.class, new InterfaceMonitorEntryKey(interfaceName)).build();
+    }
+
 }
index cd6e35d84b803ac4211d08a9f116124280a7031b..4adff7359bf11129da398b71b26375bff0b35a05 100644 (file)
@@ -36,8 +36,13 @@ public class IpMonitorStopTask implements Callable<List<ListenableFuture<Void>>>
     @Override
     public List<ListenableFuture<Void>> call() {
         final List<ListenableFuture<Void>> futures = new ArrayList<>();
-        java.util.Optional<Long> monitorIdOptional = AlivenessMonitorUtils.getMonitorIdFromInterface(macEntry);
-        monitorIdOptional.ifPresent(alivenessMonitorUtils::stopIpMonitoring);
+        java.util.Optional<Long> monitorIdOptional = alivenessMonitorUtils.getMonitorIdFromInterface(macEntry);
+        if (monitorIdOptional.isPresent()) {
+            alivenessMonitorUtils.stopIpMonitoring(monitorIdOptional.get());
+        } else {
+            LOG.warn("MonitorId not available for IP {} interface {}. IpMonitoring not stopped",
+                    macEntry.getIpAddress(), macEntry.getInterfaceName());
+        }
 
         String learntIp = macEntry.getIpAddress().getHostAddress();
         if (this.isRemoveMipAdjAndLearntIp) {