Arp cache feature changes 10/45410/20
authorGobinath <gobinath@ericsson.com>
Thu, 8 Sep 2016 14:31:48 +0000 (20:01 +0530)
committerSam Hague <shague@redhat.com>
Wed, 19 Oct 2016 16:07:40 +0000 (16:07 +0000)
Change the implementation of Arp Cache feature so that
the Arp entries learnt for the VMs are removed only when
those VMs are no longer accessible to the gateway.

1) Remove the old implementation where as soon as a VM's mac
is learnt, it is enqueued in a queue with a timer and this entry
is removed after the timer expires. After the removal from queue,
the mac and FIB entries of the VM were removed.

2) When a VM's arp is learnt, use the Aliveness Monitor module to
monitor the VM's by sending out ARP packets from gateway to the
VM periodically. The aliveness monitor module should listen to the
VpnPortIpData which would contain the ports present in the vpn.

3) Unless the monitor event "down" is received,ie,the VM is no
longer accessible from the gateway, the Mac entries for the VM are
to be retained.

4) When the monitor event "down" is received, the mac entries for
that VM and their FIB entries are to be removed.

Change-Id: I4c29e4390a1c5be0609e8ee1d682728ab0762588
Signed-off-by: Gobinath <gobinath@ericsson.com>
14 files changed:
vpnservice/vpnmanager/vpnmanager-impl/pom.xml
vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/AlivenessMonitorUtils.java [new file with mode: 0644]
vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/ArpAddCacheTask.java [deleted file]
vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/ArpConstants.java
vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/ArpMonitorEventListener.java [new file with mode: 0644]
vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/ArpMonitorStartTask.java [new file with mode: 0644]
vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/ArpMonitorStopTask.java [moved from vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/ArpUpdateCacheTask.java with 51% similarity]
vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/ArpMonitoringHandler.java [new file with mode: 0644]
vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/ArpNotificationHandler.java
vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/ArpRemoveCacheTask.java [deleted file]
vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/ArpScheduler.java [deleted file]
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
vpnservice/vpnmanager/vpnmanager-impl/src/main/resources/org/opendaylight/blueprint/vpnmanager.xml

index 1e4e621f162be5749a0b144cc737b7b09154b53f..cbb978ad916aa063ef7063a919d9cebe33d388a8 100644 (file)
@@ -101,6 +101,11 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <artifactId>lockmanager-api</artifactId>
       <version>${genius.version}</version>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.genius</groupId>
+      <artifactId>alivenessmonitor-api</artifactId>
+      <version>${genius.version}</version>
+    </dependency>
   </dependencies>
 
   <!--
diff --git a/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/AlivenessMonitorUtils.java b/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/AlivenessMonitorUtils.java
new file mode 100644 (file)
index 0000000..b52b241
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2015 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.vpnmanager;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.netvirt.neutronvpn.interfaces.INeutronVpnManager;
+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.inet.types.rev130715.Ipv4Address;
+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.EtherTypes;
+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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorProfileGetInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorProfileGetInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorProfileGetOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorStartInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorStartInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorStartOutput;
+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.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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.monitor.params.SourceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.monitor.profile.create.input.Profile;
+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.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+public class AlivenessMonitorUtils {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AlivenessMonitorUtils.class);
+    private static Map<Long, MacEntry> alivenessCache = new ConcurrentHashMap<>();
+
+    public static void startArpMonitoring(MacEntry macEntry, Long arpMonitorProfileId,
+            AlivenessMonitorService alivenessMonitorService, DataBroker dataBroker,
+            OdlInterfaceRpcService interfaceRpc, INeutronVpnManager neutronVpnService) {
+        Optional<IpAddress> gatewayIpOptional = VpnUtil.getGatewayIpAddressFromInterface(macEntry.getInterfaceName(),
+                neutronVpnService, dataBroker);
+        IpAddress gatewayIp;
+        PhysAddress gatewayMac;
+        if(!gatewayIpOptional.isPresent()) {
+            LOG.error("Error while retrieving GatewayIp for interface{}", macEntry.getInterfaceName());
+            return;
+        }
+        gatewayIp = gatewayIpOptional.get();
+        Optional<String> gatewayMacOptional = VpnUtil.getGWMacAddressFromInterface(macEntry,
+                gatewayIp, dataBroker, interfaceRpc);
+        if(!gatewayMacOptional.isPresent()) {
+            LOG.error("Error while retrieving GatewayMac for interface{}", macEntry.getInterfaceName());
+            return;
+        }
+        gatewayMac = new PhysAddress(gatewayMacOptional.get());
+        if(arpMonitorProfileId == null || arpMonitorProfileId.equals(0L)) {
+            Optional<Long> profileIdOptional = allocateProfile(alivenessMonitorService,
+                    ArpConstants.FAILURE_THRESHOLD, ArpConstants.ARP_CACHE_TIMEOUT_MILLIS,
+                    ArpConstants.MONITORING_WINDOW, EtherTypes.Arp);
+            if(!profileIdOptional.isPresent()) {
+                LOG.error("Error while allocating Profile Id for alivenessMonitorService");
+                return;
+            }
+            arpMonitorProfileId = profileIdOptional.get();
+        }
+
+        IpAddress targetIp =  new IpAddress(new Ipv4Address(macEntry.getIpAddress().getHostAddress()));
+        MonitorStartInput arpMonitorInput = new MonitorStartInputBuilder().setConfig(new ConfigBuilder()
+                .setSource(new SourceBuilder().setEndpointType(getSourceEndPointType(macEntry.getInterfaceName(),
+                        gatewayIp, gatewayMac)).build())
+                .setDestination(new DestinationBuilder().setEndpointType(getEndPointIpAddress(targetIp)).build())
+                .setMode(MonitoringMode.OneOne)
+                .setProfileId(arpMonitorProfileId).build()).build();
+        try {
+            Future<RpcResult<MonitorStartOutput>> result = alivenessMonitorService.monitorStart(arpMonitorInput);
+            RpcResult<MonitorStartOutput> rpcResult = result.get();
+            long monitorId;
+            if (rpcResult.isSuccessful()) {
+                monitorId = rpcResult.getResult().getMonitorId();
+                createOrUpdateInterfaceMonitorIdMap(monitorId, macEntry);
+                LOG.trace("Started ARP monitoring with id {}", monitorId);
+            } else {
+                LOG.warn("RPC Call to start monitoring returned with Errors {}", rpcResult.getErrors());
+            }
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.warn("Exception when starting monitoring", e);
+        }
+    }
+
+    public static void stopArpMonitoring(AlivenessMonitorService alivenessMonitorService,
+            Long monitorId) {
+        MonitorStopInput input = new MonitorStopInputBuilder().setMonitorId(monitorId).build();
+        alivenessMonitorService.monitorStop(input);
+        alivenessCache.remove(monitorId);
+        return;
+    }
+
+    private static void createOrUpdateInterfaceMonitorIdMap(long monitorId, MacEntry macEntry) {
+        alivenessCache.put(monitorId, macEntry);
+    }
+
+    private static Interface getSourceEndPointType(String interfaceName, IpAddress ipAddress,
+            PhysAddress gwMac) {
+        return new InterfaceBuilder()
+                .setInterfaceIp(ipAddress)
+                .setInterfaceName(interfaceName)
+                .setMacAddress(gwMac)
+                .build();
+    }
+
+    public static Optional<Long> allocateProfile(AlivenessMonitorService alivenessMonitor,
+            long FAILURE_THRESHOLD, long MONITORING_INTERVAL,
+            long MONITORING_WINDOW, EtherTypes etherTypes) {
+        MonitorProfileCreateInput input = new MonitorProfileCreateInputBuilder()
+                .setProfile(new ProfileBuilder().setFailureThreshold(FAILURE_THRESHOLD)
+                        .setMonitorInterval(MONITORING_INTERVAL).setMonitorWindow(MONITORING_WINDOW)
+                        .setProtocolType(etherTypes).build()).build();
+        return createMonitorProfile(alivenessMonitor, input);
+    }
+
+    public static Optional<Long> createMonitorProfile(AlivenessMonitorService alivenessMonitor,
+            MonitorProfileCreateInput monitorProfileCreateInput) {
+        Optional <Long> monitorProfileOptional = Optional.absent();
+        try {
+            Future<RpcResult<MonitorProfileCreateOutput>> result = alivenessMonitor.monitorProfileCreate(monitorProfileCreateInput);
+            RpcResult<MonitorProfileCreateOutput> rpcResult = result.get();
+            if(rpcResult.isSuccessful()) {
+                return Optional.of(rpcResult.getResult().getProfileId());
+            } else {
+                LOG.warn("RPC Call to Get Profile Id Id returned with Errors {}.. Trying to fetch existing profile ID",
+                        rpcResult.getErrors());
+                try{
+                    Profile createProfile = monitorProfileCreateInput.getProfile();
+                    Future<RpcResult<MonitorProfileGetOutput>> existingProfile =
+                            alivenessMonitor.monitorProfileGet(buildMonitorGetProfile(createProfile.getMonitorInterval(),
+                                    createProfile.getMonitorWindow(), createProfile.getFailureThreshold(), createProfile.getProtocolType()));
+                    RpcResult<MonitorProfileGetOutput> rpcGetResult = existingProfile.get();
+                    if(rpcGetResult.isSuccessful()) {
+                        return Optional.of(rpcGetResult.getResult().getProfileId());
+                    } else {
+                        LOG.warn("RPC Call to Get Existing Profile Id returned with Errors {}", rpcGetResult.getErrors());
+                    }
+                } catch(Exception e) {
+                    LOG.warn("Exception when getting existing profile", e);
+                }
+            }
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.warn("Exception when allocating profile Id", e);
+        }
+        return monitorProfileOptional;
+    }
+
+    private static MonitorProfileGetInput buildMonitorGetProfile(long monitorInterval,
+            long monitorWindow, long failureThreshold, EtherTypes protocolType) {
+        MonitorProfileGetInputBuilder buildGetProfile = new MonitorProfileGetInputBuilder();
+        org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.monitor.profile.get.input.ProfileBuilder profileBuilder =
+                new org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.monitor.profile.get.input.ProfileBuilder();
+        profileBuilder.setFailureThreshold(failureThreshold)
+        .setMonitorInterval(monitorInterval)
+        .setMonitorWindow(monitorWindow)
+        .setProtocolType(protocolType);
+        buildGetProfile.setProfile(profileBuilder.build());
+        return (buildGetProfile.build());
+    }
+
+    public static MacEntry getMacEntryFromMonitorId(Long monitorId) {
+        return alivenessCache.get(monitorId);
+    }
+
+    private static org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411
+    .endpoint.endpoint.type.IpAddress getEndPointIpAddress(IpAddress ip) {
+        return new org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411
+                .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->map.getKey())
+                .findFirst();
+        return monitorId;
+    }
+
+}
\ No newline at end of file
diff --git a/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/ArpAddCacheTask.java b/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/ArpAddCacheTask.java
deleted file mode 100644 (file)
index cf9214a..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2016 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.vpnmanager;
-
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.DelayQueue;
-
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.util.concurrent.ListenableFuture;
-
-public class ArpAddCacheTask implements Callable<List<ListenableFuture<Void>>> {
-    private InetAddress srcInetAddr;
-    private MacAddress srcMacAddress;
-    private String vpnName;
-    private String interfaceName;
-    private DelayQueue<MacEntry> macEntryQueue;
-    private static final Logger LOG = LoggerFactory.getLogger(ArpAddCacheTask.class);
-
-    public ArpAddCacheTask(InetAddress srcInetAddr, MacAddress srcMacAddress, String vpnName, String interfaceName,
-            DelayQueue<MacEntry> macEntryQueue) {
-        super();
-        this.srcInetAddr = srcInetAddr;
-        this.srcMacAddress = srcMacAddress;
-        this.vpnName = vpnName;
-        this.interfaceName = interfaceName;
-        this.macEntryQueue = macEntryQueue;
-    }
-
-    @Override
-    public List<ListenableFuture<Void>> call() throws Exception {
-        List<ListenableFuture<Void>> futures = new ArrayList<>();
-        addOrUpdateMacEntryToQueue(vpnName,srcMacAddress, srcInetAddr, interfaceName);
-        return futures;
-    }
-
-    private void addOrUpdateMacEntryToQueue(String vpnName, MacAddress macAddress,InetAddress InetAddress, String
-            interfaceName) {
-        MacEntry newMacEntry = new MacEntry(ArpConstants.ARP_CACHE_TIMEOUT_MILLIS, vpnName, macAddress, InetAddress,
-                interfaceName);
-        if (!macEntryQueue.contains(newMacEntry)) {
-            macEntryQueue.offer(newMacEntry);
-        } else {
-            macEntryQueue.remove(newMacEntry);
-            macEntryQueue.offer(newMacEntry);
-        }
-    }
-}
index c343256c73d6eb8be104a6c93cabe1983763e727..492e6cef5e8bea5bc172f6a8780ae459f74ed4a0 100644 (file)
@@ -9,22 +9,15 @@ package org.opendaylight.netvirt.vpnmanager;
 
 public class ArpConstants {
 
-        public static final int THREAD_POOL_SIZE = 5;
-        public static final int NO_DELAY = 0;
-        public static final int RETRY_COUNT = 5;
-        public static final short ARP_REQUEST_OP = (short) 1;
-        public static final short ETH_TYPE_ARP = 0x0806;
         public static final String PREFIX = "/32";
         public static final String NODE_CONNECTOR_NOT_FOUND_ERROR = "Node connector id not found for interface %s";
         public static final String FAILED_TO_GET_SRC_IP_FOR_INTERFACE = "Failed to get src ip for %s";
         public static final String FAILED_TO_GET_SRC_MAC_FOR_INTERFACE = "Failed to get src mac for interface %s iid %s ";
-        public static final int PERIOD = 10000;
         public static final String ARPJOB = "Arpcache";
-        public static final long DEFAULT_ARP_LEARNED_CACHE_TIMEOUT = 300000L; /* 300 seconds = 5 minutes */
-
+        public static final long DEFAULT_ARP_LEARNED_CACHE_TIMEOUT = 120000; /* 120 seconds = 2 minutes */
         public static final String ARP_CACHE_TIMEOUT_PROP = "arp.cache.timeout";
-
         public static long ARP_CACHE_TIMEOUT_MILLIS = Long.getLong(ArpConstants.ARP_CACHE_TIMEOUT_PROP,
                 ArpConstants.DEFAULT_ARP_LEARNED_CACHE_TIMEOUT);
-
+        public static final long FAILURE_THRESHOLD = 2;
+        public static final long MONITORING_WINDOW = 4;
 }
diff --git a/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/ArpMonitorEventListener.java b/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/ArpMonitorEventListener.java
new file mode 100644 (file)
index 0000000..0e6cde6
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2015 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.vpnmanager;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.AlivenessMonitorListener;
+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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This class listens for interface creation/removal/update in Configuration DS.
+ * This is used to handle interfaces for base of-ports.
+ */
+public class ArpMonitorEventListener implements AlivenessMonitorListener {
+    private static final Logger LOG = LoggerFactory.getLogger(ArpMonitorEventListener.class);
+    private AlivenessMonitorService alivenessManager;
+    private DataBroker dataBroker;
+
+    public ArpMonitorEventListener(DataBroker dataBroker, AlivenessMonitorService alivenessManager) {
+        this.alivenessManager = alivenessManager;
+        this.dataBroker = dataBroker;
+    }
+
+    @Override
+    public void onMonitorEvent(MonitorEvent notification) {
+        Long monitorId = notification.getEventData().getMonitorId();
+        MacEntry macEntry = AlivenessMonitorUtils.getMacEntryFromMonitorId(monitorId);
+        if(macEntry == null) {
+            LOG.debug("No MacEntry found associated with the monitor Id {}", monitorId);
+            return;
+        }
+        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));
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/ArpMonitorStartTask.java b/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/ArpMonitorStartTask.java
new file mode 100644 (file)
index 0000000..c2c0802
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016 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.vpnmanager;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.netvirt.neutronvpn.interfaces.INeutronVpnManager;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.AlivenessMonitorService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
+import com.google.common.util.concurrent.ListenableFuture;
+
+public class ArpMonitorStartTask implements Callable<List<ListenableFuture<Void>>> {
+    private MacEntry macEntry;
+    private Long arpMonitorProfileId;
+    private DataBroker databroker;
+    private AlivenessMonitorService alivenessManager;
+    private OdlInterfaceRpcService interfaceRpc;
+    private INeutronVpnManager neutronVpnService;
+
+    public ArpMonitorStartTask(MacEntry macEntry, Long profileId, DataBroker databroker,
+            AlivenessMonitorService alivenessManager, OdlInterfaceRpcService interfaceRpc,
+            INeutronVpnManager neutronVpnService) {
+        super();
+        this.macEntry = macEntry;
+        this.arpMonitorProfileId = profileId;
+        this.databroker = databroker;
+        this.alivenessManager = alivenessManager;
+        this.interfaceRpc = interfaceRpc;
+        this.neutronVpnService = neutronVpnService;
+    }
+
+    @Override
+    public List<ListenableFuture<Void>> call() throws Exception {
+        AlivenessMonitorUtils.startArpMonitoring(macEntry, arpMonitorProfileId,
+                alivenessManager, databroker, interfaceRpc, neutronVpnService);
+        return null;
+    }
+
+}
\ No newline at end of file
similarity index 51%
rename from vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/ArpUpdateCacheTask.java
rename to vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/ArpMonitorStopTask.java
index 4e2f760c24d1df49705f8446a32dcb01e07bb164..f3025c278cd3d4eff7bbd6f4c65f2cc584e3113c 100644 (file)
@@ -17,10 +17,10 @@ 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.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;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -29,27 +29,32 @@ import com.google.common.base.Optional;
 import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.ListenableFuture;
 
-public class ArpUpdateCacheTask implements Callable<List<ListenableFuture<Void>>> {
+public class ArpMonitorStopTask implements Callable<List<ListenableFuture<Void>>> {
+    private MacEntry macEntry;
+    private AlivenessMonitorService alivenessManager;
     private DataBroker dataBroker;
-    private String fixedip;
-    private String vpnName;
-    private String interfaceName;
-    private static final Logger LOG = LoggerFactory.getLogger(ArpUpdateCacheTask.class);
+    private static final Logger LOG = LoggerFactory.getLogger(ArpMonitorStopTask.class);
 
-    public ArpUpdateCacheTask(DataBroker dataBroker, String fixedip, String vpnName, String interfaceName) {
+    public ArpMonitorStopTask(MacEntry macEntry, DataBroker dataBroker,
+            AlivenessMonitorService alivenessManager) {
         super();
-        this.fixedip = fixedip;
-        this.vpnName = vpnName;
-        this.interfaceName = interfaceName;
+        this.macEntry = macEntry;
         this.dataBroker = dataBroker;
+        this.alivenessManager = alivenessManager;
     }
 
     @Override
     public List<ListenableFuture<Void>> call() throws Exception {
         List<ListenableFuture<Void>> futures = new ArrayList<>();
         WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
-        removeMipAdjacency(fixedip, vpnName, interfaceName, tx);
-        VpnUtil.removeVpnPortFixedIpToPort(dataBroker, vpnName, fixedip);
+        java.util.Optional<Long> monitorIdOptional = AlivenessMonitorUtils.getMonitorIdFromInterface(macEntry);
+        if(monitorIdOptional.isPresent()) {
+            AlivenessMonitorUtils.stopArpMonitoring(alivenessManager, monitorIdOptional.get());
+        }
+        removeMipAdjacency(macEntry.getIpAddress().getHostAddress(),
+                macEntry.getVpnName(), macEntry.getInterfaceName(), tx);
+        VpnUtil.removeVpnPortFixedIpToPort(dataBroker, macEntry.getVpnName(),
+                macEntry.getIpAddress().getHostAddress());
         CheckedFuture<Void, TransactionCommitFailedException> txFutures = tx.submit();
         try {
             txFutures.get();
@@ -60,21 +65,23 @@ public class ArpUpdateCacheTask implements Callable<List<ListenableFuture<Void>>
         return futures;
     }
 
- private void removeMipAdjacency(String fixedip, String vpnName, String interfaceName, WriteTransaction tx) {
-     synchronized (interfaceName.intern()) {
-         InstanceIdentifier<VpnInterface> vpnIfId = VpnUtil.getVpnInterfaceIdentifier(interfaceName);
-         InstanceIdentifier<Adjacencies> path = vpnIfId.augmentation(Adjacencies.class);
-         Optional<Adjacencies> adjacencies = VpnUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, path);
-         if (adjacencies.isPresent()) {
-             InstanceIdentifier<Adjacency> adid = vpnIfId.augmentation(Adjacencies.class).child(Adjacency.class, new AdjacencyKey(iptoprefix(fixedip)));
+    private void removeMipAdjacency(String fixedip, String vpnName,
+            String interfaceName, WriteTransaction tx) {
+        synchronized (interfaceName.intern()) {
+            InstanceIdentifier<VpnInterface> vpnIfId = VpnUtil.getVpnInterfaceIdentifier(interfaceName);
+            InstanceIdentifier<Adjacencies> path = vpnIfId.augmentation(Adjacencies.class);
+            Optional<Adjacencies> adjacencies = VpnUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, path);
+            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);
+            }
+        }
+    }
 
-             tx.delete(LogicalDatastoreType.CONFIGURATION, adid);
-             LOG.info("deleting the adjacencies for vpn {} interface {}", vpnName, interfaceName);
-         }
-     }
- }
+    private String ipToPrefix(String ip) {
+        return new StringBuilder(ip).append(ArpConstants.PREFIX).toString();
+    }
 
- private String iptoprefix(String ip) {
-     return new StringBuilder(ip).append(ArpConstants.PREFIX).toString();
-  }
 }
diff --git a/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/ArpMonitoringHandler.java b/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/ArpMonitoringHandler.java
new file mode 100644 (file)
index 0000000..0ef1a5f
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2015 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.vpnmanager;
+
+import java.math.BigInteger;
+import java.net.InetAddress;
+
+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.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
+import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
+import org.opendaylight.genius.mdsalutil.NwConstants;
+import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.netvirt.neutronvpn.interfaces.INeutronVpnManager;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.AlivenessMonitorService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.EtherTypes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+
+public class ArpMonitoringHandler extends AsyncDataTreeChangeListenerBase<VpnPortipToPort, ArpMonitoringHandler> {
+    private static final Logger LOG = LoggerFactory.getLogger(ArpMonitoringHandler.class);
+    private final DataBroker dataBroker;
+    private final OdlInterfaceRpcService interfaceRpc;
+    private final IMdsalApiManager mdsalManager;
+    private final AlivenessMonitorService alivenessManager;
+    private final INeutronVpnManager neutronVpnService;
+    private Long arpMonitorProfileId = 0L;
+
+    public ArpMonitoringHandler(final DataBroker dataBroker, final OdlInterfaceRpcService interfaceRpc,
+            IMdsalApiManager mdsalManager, AlivenessMonitorService alivenessManager, INeutronVpnManager neutronVpnService) {
+        super(VpnPortipToPort.class, ArpMonitoringHandler.class);
+        this.dataBroker = dataBroker;
+        this.interfaceRpc = interfaceRpc;
+        this.mdsalManager = mdsalManager;
+        this.alivenessManager = alivenessManager;
+        this.neutronVpnService = neutronVpnService;
+    }
+
+    public void start() {
+        Optional <Long> profileIdOptional = AlivenessMonitorUtils.allocateProfile(alivenessManager,
+                ArpConstants.FAILURE_THRESHOLD, ArpConstants.ARP_CACHE_TIMEOUT_MILLIS, ArpConstants.MONITORING_WINDOW,
+                EtherTypes.Arp);
+        if(profileIdOptional.isPresent()) {
+            arpMonitorProfileId = profileIdOptional.get();
+        } else {
+            LOG.error("Error while allocating Profile Id", profileIdOptional);
+        }
+        registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
+    }
+
+    @Override
+    protected InstanceIdentifier<VpnPortipToPort> getWildCardPath() {
+        return InstanceIdentifier.create(NeutronVpnPortipPortData.class).child(VpnPortipToPort.class);
+    }
+
+    public static InstanceIdentifier<VpnPortipToPort> getVpnPortipToPortInstanceOpDataIdentifier(String ip, String vpnName) {
+        return InstanceIdentifier.builder(NeutronVpnPortipPortData.class)
+                .child(VpnPortipToPort.class, new VpnPortipToPortKey(ip, vpnName)).build();
+    }
+
+    @Override
+    protected ArpMonitoringHandler getDataTreeChangeListener() {
+        return this;
+    }
+
+    @Override
+    protected void update(InstanceIdentifier<VpnPortipToPort> id, VpnPortipToPort value,
+            VpnPortipToPort dataObjectModificationAfter) {
+        try {
+            Boolean islearnt = value.isLearnt();
+            if(value.getMacAddress() == null || dataObjectModificationAfter.getMacAddress() == null) {
+                LOG.warn("The Macaddress received is null for VpnPortipToPort {}, ignoring the DTCN", dataObjectModificationAfter);
+                return;
+            }
+            if(islearnt) {
+                remove(id, value);
+                add(id, dataObjectModificationAfter);
+            }
+        } catch (Exception e) {
+            LOG.error("Error in handling update to vpnPortIpToPort for vpnName {} and IP Address {}", value.getVpnName() , value.getPortFixedip());
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    protected void add(InstanceIdentifier<VpnPortipToPort> identifier, VpnPortipToPort value) {
+        try {
+            InetAddress srcInetAddr = InetAddress.getByName(value.getPortFixedip());
+            String macAddress = value.getMacAddress();
+            if(value.getMacAddress() == null) {
+                LOG.warn("The Macaddress received is null for VpnPortipToPort {}, ignoring the DTCN", value);
+                return;
+            }
+            MacAddress srcMacAddress = MacAddress.getDefaultInstance(value.getMacAddress());
+            String vpnName =  value.getVpnName();
+            String interfaceName =  value.getPortName();
+            Boolean islearnt = value.isLearnt();
+            if (islearnt) {
+                MacEntry macEntry = new MacEntry(vpnName, srcMacAddress, srcInetAddr, interfaceName);
+                DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+                coordinator.enqueueJob(buildJobKey(srcInetAddr.toString(), vpnName),
+                        new ArpMonitorStartTask(macEntry, arpMonitorProfileId, dataBroker, alivenessManager,
+                                interfaceRpc, neutronVpnService));
+            }
+            if (value.isSubnetIp()) {
+                WriteTransaction writeTx = dataBroker.newWriteOnlyTransaction();
+                VpnUtil.setupSubnetMacIntoVpnInstance(dataBroker, mdsalManager, vpnName,
+                        macAddress, BigInteger.ZERO /* On all DPNs */, writeTx, NwConstants.ADD_FLOW);
+                writeTx.submit();
+            }
+        } catch (Exception e) {
+            LOG.error("Error in deserializing packet {} with exception {}", value, e);
+        }
+    }
+
+    @Override
+    protected void remove(InstanceIdentifier<VpnPortipToPort> key, VpnPortipToPort value) {
+        try {
+            InetAddress srcInetAddr = InetAddress.getByName(value.getPortFixedip());
+            String macAddress = value.getMacAddress();
+            if(value.getMacAddress() == null) {
+                LOG.warn("The Macaddress received is null for VpnPortipToPort {}, ignoring the DTCN", value);
+                return;
+            }
+            MacAddress srcMacAddress = MacAddress.getDefaultInstance(value.getMacAddress());
+            String vpnName =  value.getVpnName();
+            String interfaceName =  value.getPortName();
+            Boolean islearnt = value.isLearnt();
+            if (islearnt) {
+                MacEntry macEntry = new MacEntry(vpnName, srcMacAddress, srcInetAddr, interfaceName);
+                DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+                coordinator.enqueueJob(buildJobKey(srcInetAddr.toString(), vpnName),
+                        new ArpMonitorStopTask(macEntry, dataBroker, alivenessManager));
+            }
+            if (value.isSubnetIp()) {
+                WriteTransaction writeTx = dataBroker.newWriteOnlyTransaction();
+                VpnUtil.setupSubnetMacIntoVpnInstance(dataBroker, mdsalManager, vpnName,
+                        macAddress, BigInteger.ZERO /* On all DPNs */, writeTx, NwConstants.DEL_FLOW);
+                writeTx.submit();
+            }
+        } catch (Exception e) {
+            LOG.error("Error in deserializing packet {} with exception {}", value, e);
+        }
+    }
+
+    static String buildJobKey(String ip, String vpnName) {
+        return new StringBuilder(ArpConstants.ARPJOB).append(ip).append(vpnName).toString();
+    }
+}
index 6943ff58cb9c680afc6e57b2fd6401549464bfed..b0db0fcb34709238afa5d3c81407fe9e488fb87f 100644 (file)
@@ -66,12 +66,12 @@ public class ArpNotificationHandler implements OdlArputilListener {
     IdManagerService idManager;
     OdlArputilService arpManager;
     final IElanService elanService;
-    ArpScheduler arpScheduler;
+    ArpMonitoringHandler arpScheduler;
     OdlInterfaceRpcService ifaceMgrRpcService;
 
     public ArpNotificationHandler(DataBroker dataBroker, VpnInterfaceManager vpnIfMgr,
             final IElanService elanService, IdManagerService idManager, OdlArputilService arpManager,
-            ArpScheduler arpScheduler, OdlInterfaceRpcService ifaceMgrRpcService) {
+            ArpMonitoringHandler arpScheduler, OdlInterfaceRpcService ifaceMgrRpcService) {
         this.dataBroker = dataBroker;
         vpnIfManager = vpnIfMgr;
         this.elanService = elanService;
@@ -137,8 +137,6 @@ public class ArpNotificationHandler implements OdlArputilListener {
                                     oldPortName, oldMac, ipToQuery, srcMac.getValue());
                             return;
                         }
-                    } else {
-                        arpScheduler.refreshArpEntry(vpnPortipToPort);
                     }
                 } else {
                     synchronized ((vpnName + ipToQuery).intern()) {
@@ -192,6 +190,7 @@ public class ArpNotificationHandler implements OdlArputilListener {
         Optional<Port> port = VpnUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, inst);
         if (port.isPresent()) {
             prt = port.get();
+            //TODO(Gobinath): Need to fix this as assuming port will belong to only one Subnet would be incorrect"
             Uuid subnetUUID = prt.getFixedIps().get(0).getSubnetId();
             LOG.trace("Subnet UUID for this VPN Interface is {}", subnetUUID);
             SubnetKey subnetkey = new SubnetKey(subnetUUID);
@@ -255,8 +254,6 @@ public class ArpNotificationHandler implements OdlArputilListener {
                             LOG.warn("MAC Address mismatch for Interface {} having a Mac  {} , IP {} and Arp learnt Mac {}",
                                     srcInterface, oldMac, ipToQuery, srcMac.getValue());
                         }
-                    } else {
-                        arpScheduler.refreshArpEntry(vpnPortipToPort);
                     }
                 } else {
                     synchronized ((vpnName + ipToQuery).intern()) {
diff --git a/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/ArpRemoveCacheTask.java b/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/ArpRemoveCacheTask.java
deleted file mode 100644 (file)
index e14a62a..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2016 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.vpnmanager;
-
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.DelayQueue;
-
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.util.concurrent.ListenableFuture;
-
-public class ArpRemoveCacheTask implements Callable<List<ListenableFuture<Void>>> {
-    private InetAddress srcInetAddr;
-    private MacAddress srcMacAddress;
-    private String vpnName;
-    private String interfaceName;
-    private DelayQueue<MacEntry> macEntryQueue;
-    private static final Logger LOG = LoggerFactory.getLogger(ArpRemoveCacheTask.class);
-
-    public ArpRemoveCacheTask(InetAddress srcInetAddr, MacAddress srcMacAddress, String vpnName, String interfaceName,
-            DelayQueue<MacEntry> macEntryQueue) {
-        super();
-        this.srcInetAddr = srcInetAddr;
-        this.srcMacAddress = srcMacAddress;
-        this.vpnName = vpnName;
-        this.interfaceName = interfaceName;
-        this.macEntryQueue = macEntryQueue;
-    }
-
-    @Override
-    public List<ListenableFuture<Void>> call() throws Exception {
-        List<ListenableFuture<Void>> futures = new ArrayList<>();
-        removeMacEntryFromQueue(vpnName,srcMacAddress, srcInetAddr, interfaceName);
-        return futures;
-    }
-
-    private void removeMacEntryFromQueue(String vpnName, MacAddress macAddress,InetAddress InetAddress, String interfaceName) {
-        MacEntry newMacEntry = new MacEntry(ArpConstants.ARP_CACHE_TIMEOUT_MILLIS,vpnName,macAddress, InetAddress,interfaceName);
-        if (macEntryQueue.contains(newMacEntry)) {
-            macEntryQueue.remove(newMacEntry);
-        }
-    }
-}
diff --git a/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/ArpScheduler.java b/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/ArpScheduler.java
deleted file mode 100644 (file)
index fc6724b..0000000
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Copyright (c) 2015 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.vpnmanager;
-
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.ThreadFactoryBuilder;
-
-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.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
-import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
-import org.opendaylight.genius.mdsalutil.NwConstants;
-import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
-import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig;
-import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
-import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
-import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortKey;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.lang.Thread.UncaughtExceptionHandler;
-import java.math.BigInteger;
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.Collection;
-
-import java.util.List;
-import java.util.concurrent.DelayQueue;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.TimeUnit;
-
-public class ArpScheduler extends AsyncDataTreeChangeListenerBase<VpnPortipToPort,ArpScheduler> {
-    private static final Logger LOG = LoggerFactory.getLogger(ArpScheduler.class);
-    private final DataBroker dataBroker;
-    private final OdlInterfaceRpcService intfRpc;
-    private final IMdsalApiManager mdsalManager;
-    private ScheduledExecutorService executorService;
-    private  volatile static ArpScheduler arpScheduler = null;
-    private static DelayQueue<MacEntry> macEntryQueue = new DelayQueue<MacEntry>();
-
-    public ArpScheduler(final DataBroker dataBroker, final OdlInterfaceRpcService interfaceRpc, final IMdsalApiManager mdsalManager) {
-        super(VpnPortipToPort.class, ArpScheduler.class);
-        this.dataBroker = dataBroker;
-        this.intfRpc = interfaceRpc;
-        this.mdsalManager = mdsalManager;
-    }
-
-    public void start() {
-        LOG.info("{} start", getClass().getSimpleName());
-        registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
-        executorService = Executors.newScheduledThreadPool(ArpConstants.THREAD_POOL_SIZE, getThreadFactory("Arp Cache Timer Tasks"));
-        scheduleExpiredEntryDrainerTask();
-    }
-
-    @Override
-    protected InstanceIdentifier<VpnPortipToPort> getWildCardPath() {
-        return InstanceIdentifier.create(NeutronVpnPortipPortData.class).child(VpnPortipToPort.class);
-    }
-
-    private void scheduleExpiredEntryDrainerTask() {
-        LOG.info("Scheduling expired entry drainer task");
-        ExpiredEntryDrainerTask expiredEntryDrainerTask = new ExpiredEntryDrainerTask();
-        executorService.scheduleAtFixedRate(expiredEntryDrainerTask, ArpConstants.NO_DELAY, ArpConstants.PERIOD, TimeUnit.MILLISECONDS);
-    }
-
-    private ThreadFactory getThreadFactory(String threadNameFormat) {
-        ThreadFactoryBuilder builder = new ThreadFactoryBuilder();
-        builder.setNameFormat(threadNameFormat);
-        builder.setUncaughtExceptionHandler( new UncaughtExceptionHandler() {
-            @Override
-            public void uncaughtException(Thread t, Throwable e) {
-                LOG.error("Received Uncaught Exception event in Thread: {}", t.getName(), e);
-            }
-        });
-        return builder.build();
-    }
-
-    private class ExpiredEntryDrainerTask implements Runnable {
-        @Override
-        public void run() {
-            Collection<MacEntry> expiredMacEntries = new ArrayList<>();
-            macEntryQueue.drainTo(expiredMacEntries);
-            for (MacEntry macEntry: expiredMacEntries) {
-                LOG.info("Removing the ARP cache for"+macEntry);
-                InstanceIdentifier<VpnPortipToPort> id = getVpnPortipToPortInstanceOpDataIdentifier(macEntry.getIpAddress().getHostAddress(),macEntry.getVpnName());
-                Optional<VpnPortipToPort> vpnPortipToPort = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
-                if (vpnPortipToPort.isPresent()) {
-                    VpnPortipToPort vpnPortipToPortold = vpnPortipToPort.get();
-                    String fixedip = vpnPortipToPortold.getPortFixedip();
-                    String vpnName =  vpnPortipToPortold.getVpnName();
-                    String interfaceName =  vpnPortipToPortold.getPortName();
-                    DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
-                    coordinator.enqueueJob(buildJobKey(fixedip,vpnName),
-                            new ArpUpdateCacheTask(dataBroker,fixedip, vpnName,interfaceName));
-                }
-
-            }
-        }
-    }
-
-    private String getRouteDistinguisher(String vpnName) {
-        InstanceIdentifier<VpnInstance> id = InstanceIdentifier.builder(VpnInstances.class)
-                .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
-        Optional<VpnInstance> vpnInstance = VpnUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
-        String rd = "";
-        if(vpnInstance.isPresent()) {
-            VpnInstance instance = vpnInstance.get();
-            VpnAfConfig config = instance.getIpv4Family();
-            rd = config.getRouteDistinguisher();
-        }
-        return rd;
-    }
-
-    public static InstanceIdentifier<VpnPortipToPort> getVpnPortipToPortInstanceOpDataIdentifier(String ip,String vpnName) {
-        return InstanceIdentifier.builder(NeutronVpnPortipPortData.class)
-                .child(VpnPortipToPort.class, new VpnPortipToPortKey(ip,vpnName)).build();
-    }
-
-    @Override
-    protected ArpScheduler getDataTreeChangeListener() {
-        return this;
-    }
-
-    @Override
-    protected void update(InstanceIdentifier<VpnPortipToPort> id, VpnPortipToPort value,
-            VpnPortipToPort dataObjectModificationAfter) {
-        try {
-            InetAddress srcInetAddr = InetAddress.getByName(value.getPortFixedip());
-            String oldMacAddress = value.getMacAddress();
-            MacAddress srcMacAddress = MacAddress.getDefaultInstance(oldMacAddress);
-            String newMacAddress = dataObjectModificationAfter.getMacAddress();
-            String vpnName =  value.getVpnName();
-            String interfaceName =  value.getPortName();
-            Boolean islearnt = value.isLearnt();
-            if (islearnt) {
-                DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
-                coordinator.enqueueJob(buildJobKey(srcInetAddr.toString(), vpnName),
-                        new ArpAddCacheTask(srcInetAddr, srcMacAddress, vpnName, interfaceName, macEntryQueue));
-            } else if (dataObjectModificationAfter.isSubnetIp() && !oldMacAddress.equalsIgnoreCase(newMacAddress)) {
-                WriteTransaction writeTx = dataBroker.newWriteOnlyTransaction();
-                VpnUtil.setupSubnetMacIntoVpnInstance(dataBroker, mdsalManager, vpnName,
-                        oldMacAddress, BigInteger.ZERO /* On all DPNs */, writeTx, NwConstants.DEL_FLOW);
-                VpnUtil.setupSubnetMacIntoVpnInstance(dataBroker, mdsalManager, vpnName,
-                        newMacAddress, BigInteger.ZERO /* on all DPNs */, writeTx, NwConstants.ADD_FLOW);
-                writeTx.submit();
-            }
-        } catch (Exception e) {
-            LOG.error("Error in deserializing packet {} with exception {}", value, e);
-            e.printStackTrace();
-        }
-    }
-
-    @Override
-    protected void add(InstanceIdentifier<VpnPortipToPort> identifier, VpnPortipToPort value) {
-        try {
-            InetAddress srcInetAddr = InetAddress.getByName(value.getPortFixedip());
-            String macAddress = value.getMacAddress();
-            MacAddress srcMacAddress = MacAddress.getDefaultInstance(macAddress);
-            String vpnName =  value.getVpnName();
-            String interfaceName =  value.getPortName();
-            Boolean islearnt = value.isLearnt();
-            if (islearnt) {
-                DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
-                coordinator.enqueueJob(buildJobKey(srcInetAddr.toString(),vpnName),
-                        new ArpAddCacheTask(srcInetAddr, srcMacAddress, vpnName, interfaceName, macEntryQueue));
-            }
-            if (value.isSubnetIp()) {
-                WriteTransaction writeTx = dataBroker.newWriteOnlyTransaction();
-                VpnUtil.setupSubnetMacIntoVpnInstance(dataBroker, mdsalManager, vpnName,
-                        macAddress, BigInteger.ZERO /* On all DPNs */, writeTx, NwConstants.ADD_FLOW);
-                writeTx.submit();
-            }
-        }
-        catch (Exception e) {
-            LOG.error("Error in deserializing packet {} with exception {}", value, e);
-        }
-    }
-
-    @Override
-    protected void remove(InstanceIdentifier<VpnPortipToPort> key, VpnPortipToPort value) {
-        try {
-            InetAddress srcInetAddr = InetAddress.getByName(value.getPortFixedip());
-            String macAddress = value.getMacAddress();
-            MacAddress srcMacAddress = MacAddress.getDefaultInstance(macAddress);
-            String vpnName =  value.getVpnName();
-            String interfaceName =  value.getPortName();
-            Boolean islearnt = value.isLearnt();
-            if (islearnt) {
-                DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
-                coordinator.enqueueJob(buildJobKey(srcInetAddr.toString(),vpnName),
-                        new ArpRemoveCacheTask(srcInetAddr, srcMacAddress, vpnName,interfaceName, macEntryQueue));
-            }
-            if (value.isSubnetIp()) {
-                WriteTransaction writeTx = dataBroker.newWriteOnlyTransaction();
-                VpnUtil.setupSubnetMacIntoVpnInstance(dataBroker, mdsalManager, vpnName,
-                        macAddress, BigInteger.ZERO /* On all DPNs */, writeTx, NwConstants.DEL_FLOW);
-                writeTx.submit();
-            }
-        } catch (Exception e) {
-            LOG.error("Error in deserializing packet {} with exception {}", value, e);
-        }
-    }
-
-    private String buildJobKey(String ip, String vpnName){
-        return new StringBuilder(ArpConstants.ARPJOB).append(ip).append(vpnName).toString();
-    }
-
-    public void refreshArpEntry(VpnPortipToPort value) {
-        try {
-            InetAddress srcInetAddr = InetAddress.getByName(value.getPortFixedip());
-            MacAddress srcMacAddress = MacAddress.getDefaultInstance(value.getMacAddress());
-            String vpnName =  value.getVpnName();
-            String interfaceName =  value.getPortName();
-            Boolean islearnt = value.isLearnt();
-            if (islearnt) {
-                DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
-                coordinator.enqueueJob(buildJobKey(srcInetAddr.toString(), vpnName),
-                        new ArpAddCacheTask(srcInetAddr, srcMacAddress, vpnName, interfaceName, macEntryQueue));
-            }
-        } catch (Exception e) {
-            LOG.error("Error in deserializing packet {} with exception {}", value, e);
-        }
-    }
-}
index 8b6b24c7882ec4aa2185a96495415f4182df3de0..a48488229bdc25394c7b9f46357b8d5c39082cb0 100644 (file)
@@ -7,22 +7,17 @@
  */
 package org.opendaylight.netvirt.vpnmanager;
 
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
-
 import java.net.InetAddress;
-import java.util.concurrent.Delayed;
-import java.util.concurrent.TimeUnit;
-
-public class MacEntry implements Delayed {
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
 
-    private long expiryTime;
+public class MacEntry {
     private String vpnName;
     private MacAddress macAddress;
     private InetAddress ipAddress;
     private String interfaceName;
 
-    public MacEntry(long delay, String vpnName, MacAddress macAddress, InetAddress inetAddress, String interfaceName) {
-        this.expiryTime = System.currentTimeMillis() + delay;
+    public MacEntry(String vpnName, MacAddress macAddress,
+            InetAddress inetAddress, String interfaceName) {
         this.vpnName = vpnName;
         this.macAddress = macAddress;
         this.ipAddress = inetAddress;
@@ -37,13 +32,6 @@ public class MacEntry implements Delayed {
         this.vpnName = vpnName;
     }
 
-
-    @Override
-    public String toString() {
-        return "MacEntry [expiryTime=" + expiryTime + ", vpnName=" + vpnName + ", macAddress=" + macAddress
-              + ", ipAddress=" + ipAddress + ", interfaceName=" + interfaceName + "]";
-    }
-
     public MacAddress getMacAddress() {
         return macAddress;
     }
@@ -60,24 +48,6 @@ public class MacEntry implements Delayed {
         return ipAddress;
     }
 
-
-    @Override
-    public int compareTo(Delayed obj) {
-        if (this.expiryTime < ((MacEntry) obj).expiryTime) {
-            return -1;
-        } else if (this.expiryTime > ((MacEntry) obj).expiryTime) {
-            return 1;
-        } else {
-            return 0;
-        }
-    }
-
-    @Override
-    public long getDelay(TimeUnit arg0) {
-        long diff = expiryTime - System.currentTimeMillis();
-        return arg0.convert(diff, TimeUnit.MILLISECONDS);
-    }
-
     @Override
     public int hashCode() {
         final int prime = 31;
@@ -92,12 +62,17 @@ public class MacEntry implements Delayed {
         boolean result = false;
         if (getClass() != obj.getClass())
             return result;
-        else{
-        MacEntry other = (MacEntry) obj;
-        result = vpnName.equals(other.vpnName) && macAddress.equals(other.macAddress) && ipAddress.equals(other.ipAddress) && interfaceName.equals(other.interfaceName);
+        else {
+            MacEntry other = (MacEntry) obj;
+            result = vpnName.equals(other.vpnName) && macAddress.equals(other.macAddress)
+                    && ipAddress.equals(other.ipAddress) && interfaceName.equals(other.interfaceName);
         }
         return result;
     }
 
-
+    @Override
+    public String toString() {
+        return "MacEntry [vpnName=" + vpnName + ", macAddress=" + macAddress + ", ipAddress=" + ipAddress
+                + ", interfaceName=" + interfaceName + "]";
+    }
 }
index e8a2d247700906baabaea3595ca79b2807b67626..3c54bb52d4354906b19775c3db0b0cf788e842d5 100644 (file)
@@ -8,6 +8,9 @@
 
 package org.opendaylight.netvirt.vpnmanager;
 
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
 import java.math.BigInteger;
 import java.net.InetAddress;
 import java.util.ArrayList;
@@ -32,6 +35,7 @@ import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 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.mdsalutil.MDSALDataStoreUtils;
 import org.opendaylight.genius.mdsalutil.MDSALUtil;
 import org.opendaylight.genius.mdsalutil.NwConstants;
 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
@@ -44,8 +48,8 @@ import org.opendaylight.genius.mdsalutil.MatchInfo;
 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
+import org.opendaylight.netvirt.neutronvpn.interfaces.INeutronVpnManager;
 import org.opendaylight.netvirt.vpnmanager.utilities.InterfaceUtils;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.bgp.rev130715.bgp.neighbors.bgp.neighbor.peer.address.type.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
@@ -55,9 +59,12 @@ import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev14081
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceBuilder;
+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.interfaces.rev140508.Interfaces;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.LockManagerService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.TimeUnits;
@@ -65,8 +72,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev16041
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.TryLockInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.UnlockInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.UnlockInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
@@ -116,6 +126,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev15033
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdPools;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.id.pools.IdPool;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.id.pools.IdPoolKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
@@ -125,10 +136,14 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.IfIndexesInterfaceMap;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._if.indexes._interface.map.IfIndexInterface;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._if.indexes._interface.map.IfIndexInterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.L3nexthop;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.l3nexthop.VpnNexthops;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.l3nexthop.VpnNexthopsKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.RouterInterfacesMap;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
@@ -138,7 +153,16 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev15060
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.PortKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.InterVpnLinkStates;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.InterVpnLinks;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.link.states.InterVpnLinkState;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.link.states.InterVpnLinkStateKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.links.InterVpnLink;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.RouterInterfacesMap;
 import org.opendaylight.yangtools.yang.common.RpcResult;
@@ -1336,4 +1360,40 @@ public class VpnUtil {
             throw new RuntimeException(String.format("Unable to unlock subnetId %s", subnetId), e.getCause());
         }
     }
+
+    static Optional<IpAddress> getGatewayIpAddressFromInterface(String srcInterface,
+            INeutronVpnManager neutronVpnService, DataBroker dataBroker) {
+        Optional <IpAddress> gatewayIp = Optional.absent();
+        Port port = neutronVpnService.getNeutronPort(srcInterface);
+        //TODO(Gobinath): Need to fix this as assuming port will belong to only one Subnet would be incorrect"
+        gatewayIp = Optional.of(neutronVpnService.getNeutronSubnet(port.getFixedIps().get(0).getSubnetId()).getGatewayIp());
+        return gatewayIp;
+    }
+
+    static Optional<String> getGWMacAddressFromInterface(MacEntry macEntry, IpAddress gatewayIp,
+            DataBroker dataBroker, OdlInterfaceRpcService interfaceRpc) {
+        Optional <String> gatewayMac = Optional.absent();
+        long vpnId = getVpnId(dataBroker, macEntry.getVpnName());
+        InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds>
+        vpnIdsInstanceIdentifier = VpnUtil.getVpnIdToVpnInstanceIdentifier(vpnId);
+        Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds> vpnIdsOptional
+        = VpnUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIdsInstanceIdentifier);
+        if (!vpnIdsOptional.isPresent()) {
+            LOG.trace("VPN {} not configured", vpnId);
+            return gatewayMac;
+        }
+        VpnPortipToPort vpnTargetIpToPort = VpnUtil.getNeutronPortFromVpnPortFixedIp(dataBroker,
+                macEntry.getVpnName(), gatewayIp.getIpv4Address().getValue());
+        if (vpnTargetIpToPort != null && vpnTargetIpToPort.isSubnetIp()) {
+            gatewayMac = Optional.of(vpnTargetIpToPort.getMacAddress());
+        } else {
+            org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds vpnIds = vpnIdsOptional.get();
+            if(vpnIds.isExternalVpn()) {
+                gatewayMac = InterfaceUtils.getMacAddressForInterface(dataBroker, macEntry.getInterfaceName());
+            }
+        }
+        return gatewayMac;
+
+    }
+
 }
\ No newline at end of file
index 7b09c1b0e30814265d5181c8be10477c947c0cb0..5df6c078f4c36cf0aa81b04313e1bf32268e9b0c 100644 (file)
@@ -16,6 +16,9 @@
              interface="org.opendaylight.netvirt.elanmanager.api.IElanService" />
   <reference id="fibManager"
              interface="org.opendaylight.netvirt.fibmanager.api.IFibManager" />
+  <reference id="neutronVpnService"
+             interface="org.opendaylight.netvirt.neutronvpn.interfaces.INeutronVpnManager"
+             availability="optional" />
 
   <odl:rpc-service id="idManagerService"
                    interface="org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService" />
@@ -29,6 +32,8 @@
                    interface="org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService" />
   <odl:rpc-service id="lockManagerService"
                    interface="org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.LockManagerService" />
+  <odl:rpc-service id="alivenessManager"
+                   interface="org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.AlivenessMonitorService" />
 
   <bean id="dpnInVpnChangeListener"
         class="org.opendaylight.netvirt.vpnmanager.DpnInVpnChangeListener">
     <argument ref="vpnInterfaceManager" />
   </bean>
 
-  <bean id="arpScheduler"
-        class="org.opendaylight.netvirt.vpnmanager.ArpScheduler"
+  <bean id="arpMonitorEventListener"
+        class="org.opendaylight.netvirt.vpnmanager.ArpMonitorEventListener">
+    <argument ref="dataBroker" />
+    <argument ref="alivenessManager" />
+  </bean>
+  <odl:notification-listener ref="arpMonitorEventListener" />
+
+  <bean id="arpMonitoringHandler"
+        class="org.opendaylight.netvirt.vpnmanager.ArpMonitoringHandler"
         init-method="start" destroy-method="close">
     <argument ref="dataBroker" />
     <argument ref="odlInterfaceRpcService" />
     <argument ref="mdsalUtils" />
+    <argument ref="alivenessManager" />
+    <argument ref="neutronVpnService" />
   </bean>
 
   <bean id="subnetRoutePacketInHandler"
     <argument ref="elanService" />
     <argument ref="idManagerService" />
     <argument ref="odlArputilService" />
-    <argument ref="arpScheduler" />
+    <argument ref="arpMonitoringHandler" />
     <argument ref="odlInterfaceRpcService" />
   </bean>
   <service ref="arpNotificationHandler" odl:type="default"