<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>
<!--
--- /dev/null
+/*
+ * 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
+++ /dev/null
-/*
- * 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);
- }
- }
-}
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;
}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
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;
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();
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();
- }
}
--- /dev/null
+/*
+ * 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();
+ }
+}
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;
oldPortName, oldMac, ipToQuery, srcMac.getValue());
return;
}
- } else {
- arpScheduler.refreshArpEntry(vpnPortipToPort);
}
} else {
synchronized ((vpnName + ipToQuery).intern()) {
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);
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()) {
+++ /dev/null
-/*
- * 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);
- }
- }
-}
+++ /dev/null
-/*
- * 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);
- }
- }
-}
*/
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;
this.vpnName = vpnName;
}
-
- @Override
- public String toString() {
- return "MacEntry [expiryTime=" + expiryTime + ", vpnName=" + vpnName + ", macAddress=" + macAddress
- + ", ipAddress=" + ipAddress + ", interfaceName=" + interfaceName + "]";
- }
-
public MacAddress getMacAddress() {
return macAddress;
}
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;
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 + "]";
+ }
}
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;
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;
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;
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;
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;
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;
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;
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;
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
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" />
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"