import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import java.util.HashSet;
import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
+import javax.annotation.CheckReturnValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Inject;
import org.apache.commons.lang3.StringUtils;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
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.ReadFailedException;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
import org.opendaylight.genius.interfacemanager.globals.InterfaceServiceUtil;
import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
import org.opendaylight.genius.mdsalutil.packet.Ethernet;
import org.opendaylight.genius.mdsalutil.packet.IPv4;
import org.opendaylight.infrautils.utils.concurrent.JdkFutures;
+import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
import org.opendaylight.netvirt.elan.ElanException;
import org.opendaylight.netvirt.elan.arp.responder.ArpResponderUtil;
+import org.opendaylight.netvirt.elan.cache.ElanInterfaceCache;
import org.opendaylight.netvirt.elanmanager.api.ElanHelper;
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.IpAddressBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.RemoveTerminatingServiceActionsInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.RemoveTerminatingServiceActionsInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.RemoveTerminatingServiceActionsOutput;
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.nodes.Node;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.tag.name.map.ElanTagNameBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.tag.name.map.ElanTagNameKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.forwarding.entries.MacEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.forwarding.entries.MacEntryBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.forwarding.entries.MacEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
private static final Logger LOG = LoggerFactory.getLogger(ElanUtils.class);
- private static Map<String, ElanInstance> elanInstanceLocalCache = new ConcurrentHashMap<>();
- private static Map<String, ElanInterface> elanInterfaceLocalCache = new ConcurrentHashMap<>();
- private static Map<String, Set<DpnInterfaces>> elanInstancToDpnsCache = new ConcurrentHashMap<>();
- private static Map<String, Set<String>> elanInstanceToInterfacesCache = new ConcurrentHashMap<>();
-
private final DataBroker broker;
+ private final ManagedNewTransactionRunner txRunner;
private final IMdsalApiManager mdsalManager;
private final OdlInterfaceRpcService interfaceManagerRpcService;
private final ItmRpcService itmRpcService;
private final ElanConfig elanConfig;
private final ElanItmUtils elanItmUtils;
private final ElanEtreeUtils elanEtreeUtils;
+ private final ElanInterfaceCache elanInterfaceCache;
public static final FutureCallback<Void> DEFAULT_CALLBACK = new FutureCallback<Void>() {
@Override
@Inject
public ElanUtils(DataBroker dataBroker, IMdsalApiManager mdsalManager,
OdlInterfaceRpcService interfaceManagerRpcService, ItmRpcService itmRpcService, ElanConfig elanConfig,
- IInterfaceManager interfaceManager, ElanEtreeUtils elanEtreeUtils, ElanItmUtils elanItmUtils) {
+ IInterfaceManager interfaceManager, ElanEtreeUtils elanEtreeUtils, ElanItmUtils elanItmUtils,
+ ElanInterfaceCache elanInterfaceCache) {
this.broker = dataBroker;
+ this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
this.mdsalManager = mdsalManager;
this.interfaceManagerRpcService = interfaceManagerRpcService;
this.itmRpcService = itmRpcService;
this.elanConfig = elanConfig;
this.elanEtreeUtils = elanEtreeUtils;
this.elanItmUtils = elanItmUtils;
+ this.elanInterfaceCache = elanInterfaceCache;
}
public final Boolean isOpenstackVniSemanticsEnforced() {
? elanConfig.isOpenstackVniSemanticsEnforced() : false;
}
- public static void addElanInstanceIntoCache(String elanInstanceName, ElanInstance elanInstance) {
- elanInstanceLocalCache.put(elanInstanceName, elanInstance);
- }
-
- public static void removeElanInstanceFromCache(String elanInstanceName) {
- elanInstanceLocalCache.remove(elanInstanceName);
- }
-
- public static ElanInstance getElanInstanceFromCache(String elanInstanceName) {
- return elanInstanceLocalCache.get(elanInstanceName);
- }
-
- public static Set<String> getAllElanNames() {
- return elanInstanceLocalCache.keySet();
- }
-
- public static void addElanInterfaceIntoCache(String interfaceName, ElanInterface elanInterface) {
- elanInterfaceLocalCache.put(interfaceName, elanInterface);
- }
-
- public static void removeElanInterfaceFromCache(String interfaceName) {
- elanInterfaceLocalCache.remove(interfaceName);
- }
-
- public static ElanInterface getElanInterfaceFromCache(String interfaceName) {
- return elanInterfaceLocalCache.get(interfaceName);
- }
-
/**
* Uses the IdManager to retrieve a brand new ElanTag.
*
*
* @deprecated Consider using {@link #read2(LogicalDatastoreType, InstanceIdentifier)} with proper exception
* handling instead
+ * @param broker dataBroker
+ * @param datastoreType Logical DataStore type
+ * @param path IID to read
+ * @param <T> T extends DataObject
+ * @return the read value T
*/
@Deprecated
@SuppressWarnings("checkstyle:IllegalCatch")
}
}
+ @SuppressWarnings("checkstyle:ForbiddenMethod")
public static <T extends DataObject> void delete(DataBroker broker, LogicalDatastoreType datastoreType,
InstanceIdentifier<T> path) {
WriteTransaction tx = broker.newWriteOnlyTransaction();
Futures.addCallback(tx.submit(), DEFAULT_CALLBACK, MoreExecutors.directExecutor());
}
+ @SuppressWarnings("checkstyle:ForbiddenMethod")
public static <T extends DataObject> void delete(DataBroker broker, LogicalDatastoreType datastoreType,
InstanceIdentifier<T> path, FutureCallback<Void> callback) {
WriteTransaction tx = broker.newWriteOnlyTransaction();
return InstanceIdentifier.builder(ElanInstances.class).child(ElanInstance.class).build();
}
- // elan-instances config container
- @Nullable
- public static ElanInstance getElanInstanceByName(DataBroker broker, String elanInstanceName) {
- ElanInstance elanObj = getElanInstanceFromCache(elanInstanceName);
- if (elanObj != null) {
- return elanObj;
- }
- InstanceIdentifier<ElanInstance> elanIdentifierId =
- ElanHelper.getElanInstanceConfigurationDataPath(elanInstanceName);
- return MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, elanIdentifierId).orNull();
- }
-
- // elan-interfaces Config Container
- public static ElanInterface getElanInterfaceByElanInterfaceName(DataBroker broker, String elanInterfaceName) {
- ElanInterface elanInterfaceObj = getElanInterfaceFromCache(elanInterfaceName);
- if (elanInterfaceObj != null) {
- return elanInterfaceObj;
- }
- InstanceIdentifier<ElanInterface> elanInterfaceId = getElanInterfaceConfigurationDataPathId(elanInterfaceName);
- return MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, elanInterfaceId).orNull();
- }
-
- public static EtreeInterface getEtreeInterfaceByElanInterfaceName(DataBroker broker, String elanInterfaceName) {
- ElanInterface elanInterface = getElanInterfaceByElanInterfaceName(broker, elanInterfaceName);
- if (elanInterface == null) {
- return null;
- } else {
- return elanInterface.getAugmentation(EtreeInterface.class);
- }
- }
-
public static InstanceIdentifier<ElanInterface> getElanInterfaceConfigurationDataPathId(String interfaceName) {
return InstanceIdentifier.builder(ElanInterfaces.class)
.child(ElanInterface.class, new ElanInterfaceKey(interfaceName)).build();
return MDSALUtil.read(broker, LogicalDatastoreType.OPERATIONAL, elanIdentifier).orNull();
}
+ @Nullable
+ public static Elan getElanByName(ReadTransaction tx, String elanInstanceName) throws ReadFailedException {
+ return tx.read(LogicalDatastoreType.OPERATIONAL,
+ getElanInstanceOperationalDataPath(elanInstanceName)).checkedGet().orNull();
+ }
+
public static InstanceIdentifier<Elan> getElanInstanceOperationalDataPath(String elanInstanceName) {
return InstanceIdentifier.builder(ElanState.class).child(Elan.class, new ElanKey(elanInstanceName)).build();
}
return read(broker, LogicalDatastoreType.OPERATIONAL, macId);
}
+ public Optional<MacEntry> getMacEntryForElanInstance(ReadTransaction tx, String elanName, PhysAddress physAddress)
+ throws ReadFailedException {
+ InstanceIdentifier<MacEntry> macId = getMacEntryOperationalDataPath(elanName, physAddress);
+ return tx.read(LogicalDatastoreType.OPERATIONAL, macId).checkedGet();
+ }
+
public MacEntry getMacEntryFromElanMacId(InstanceIdentifier identifier) {
Optional<MacEntry> existingInterfaceMacEntry = read(broker,
LogicalDatastoreType.OPERATIONAL, identifier);
List<InstructionInfo> mkInstructions = new ArrayList<>();
mkInstructions.add(new InstructionGotoTable(NwConstants.ELAN_DMAC_TABLE));
BigInteger dpId = interfaceInfo.getDpId();
- long elanTag = getElanTag(broker, elanInfo, interfaceInfo);
+ long elanTag = getElanTag(elanInfo, interfaceInfo);
return new FlowEntityBuilder()
.setDpnId(dpId)
.setTableId(NwConstants.ELAN_SMAC_TABLE)
.build();
}
- private static Long getElanTag(DataBroker broker, ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
- EtreeInterface etreeInterface = getEtreeInterfaceByElanInterfaceName(broker, interfaceInfo.getInterfaceName());
+ private Long getElanTag(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
+ EtreeInterface etreeInterface = elanInterfaceCache.getEtreeInterface(interfaceInfo.getInterfaceName()).orNull();
if (etreeInterface == null || etreeInterface.getEtreeInterfaceType() == EtreeInterfaceType.Root) {
return elanInfo.getElanTag();
} else { // Leaf
- EtreeInstance etreeInstance = elanInfo.getAugmentation(EtreeInstance.class);
+ EtreeInstance etreeInstance = elanInfo.augmentation(EtreeInstance.class);
if (etreeInstance == null) {
LOG.warn("EtreeInterface {} is connected to a non-Etree network: {}",
interfaceInfo.getInterfaceName(), elanInfo.getElanInstanceName());
Flow flowEntity = buildLocalDmacFlowEntry(elanTag, dpId, ifName, macAddress, elanInfo, ifTag);
mdsalApiManager.addFlowToTx(dpId, flowEntity, writeFlowGroupTx);
installEtreeLocalDmacFlow(elanTag, dpId, ifName, macAddress, elanInfo,
- mdsalApiManager, ifTag, writeFlowGroupTx);
+ ifTag, writeFlowGroupTx);
}
private void installEtreeLocalDmacFlow(long elanTag, BigInteger dpId, String ifName, String macAddress,
- ElanInstance elanInfo, IMdsalApiManager mdsalApiManager, long ifTag, WriteTransaction writeFlowGroupTx) {
- EtreeInterface etreeInterface = getEtreeInterfaceByElanInterfaceName(broker, ifName);
- if (etreeInterface != null) {
- if (etreeInterface.getEtreeInterfaceType() == EtreeInterfaceType.Root) {
- EtreeLeafTagName etreeTagName = elanEtreeUtils.getEtreeLeafTagByElanTag(elanTag);
- if (etreeTagName == null) {
- LOG.warn("Interface {} seems like it belongs to Etree but etreeTagName from elanTag {} is null",
- ifName, elanTag);
- } else {
- Flow flowEntity = buildLocalDmacFlowEntry(etreeTagName.getEtreeLeafTag().getValue(), dpId, ifName,
- macAddress, elanInfo, ifTag);
- mdsalApiManager.addFlowToTx(dpId, flowEntity, writeFlowGroupTx);
- }
+ ElanInstance elanInfo, long ifTag, WriteTransaction writeFlowGroupTx) {
+ EtreeInterface etreeInterface = elanInterfaceCache.getEtreeInterface(ifName).orNull();
+ if (etreeInterface != null && etreeInterface.getEtreeInterfaceType() == EtreeInterfaceType.Root) {
+ EtreeLeafTagName etreeTagName = elanEtreeUtils.getEtreeLeafTagByElanTag(elanTag);
+ if (etreeTagName == null) {
+ LOG.warn("Interface {} seems like it belongs to Etree but etreeTagName from elanTag {} is null",
+ ifName, elanTag);
+ } else {
+ Flow flowEntity = buildLocalDmacFlowEntry(etreeTagName.getEtreeLeafTag().getValue(), dpId, ifName,
+ macAddress, elanInfo, ifTag);
+ mdsalManager.addFlowToTx(dpId, flowEntity, writeFlowGroupTx);
}
}
}
public static String getKnownDynamicmacFlowRef(short tableId, BigInteger dpId, long lporTag, String macAddress,
long elanTag) {
- return new StringBuffer().append(tableId).append(elanTag).append(dpId).append(lporTag).append(macAddress)
- .toString();
+ return String.valueOf(tableId) + elanTag + dpId + lporTag + macAddress;
}
public static String getKnownDynamicmacFlowRef(short tableId, BigInteger dpId, BigInteger remoteDpId,
String macAddress, long elanTag) {
- return new StringBuffer().append(tableId).append(elanTag).append(dpId).append(remoteDpId).append(macAddress)
- .toString();
+ return String.valueOf(tableId) + elanTag + dpId + remoteDpId + macAddress;
}
public static String getKnownDynamicmacFlowRef(short tableId, BigInteger dpId, String macAddress, long elanTag) {
- return new StringBuffer().append(tableId).append(elanTag).append(dpId).append(macAddress).toString();
+ return String.valueOf(tableId) + elanTag + dpId + macAddress;
}
public static String getKnownDynamicmacFlowRef(short elanDmacTable, BigInteger dpId, String extDeviceNodeId,
String dstMacAddress, long elanTag, boolean shFlag) {
- return new StringBuffer().append(elanDmacTable).append(elanTag).append(dpId).append(extDeviceNodeId)
- .append(dstMacAddress).append(shFlag).toString();
+ return String.valueOf(elanDmacTable) + elanTag + dpId + extDeviceNodeId + dstMacAddress + shFlag;
}
/**
Flow flowEntity;
// if openstack-vni-semantics are enforced, segmentation ID is passed as network VNI for VxLAN based provider
// networks, 0 otherwise
- long lportTagOrVni = !isOpenstackVniSemanticsEnforced() ? lportTag : isVxlan(elanInstance)
- ? elanInstance.getSegmentationId() : 0;
+ long lportTagOrVni = !isOpenstackVniSemanticsEnforced() ? lportTag : isVxlanNetworkOrVxlanSegment(elanInstance)
+ ? getVxlanSegmentationId(elanInstance) : 0;
flowEntity = buildRemoteDmacFlowEntry(srcDpId, destDpId, lportTagOrVni, elanTag, macAddress, displayName,
elanInstance);
mdsalManager.addFlowToTx(srcDpId, flowEntity, writeFlowGroupTx);
private void setupEtreeRemoteDmacFlow(BigInteger srcDpId, BigInteger destDpId, long lportTagOrVni, long elanTag,
String macAddress, String displayName, String interfaceName,
- WriteTransaction writeFlowGroupTx, ElanInstance elanInstance)
- throws ElanException {
+ WriteTransaction writeFlowGroupTx, ElanInstance elanInstance) {
Flow flowEntity;
- EtreeInterface etreeInterface = getEtreeInterfaceByElanInterfaceName(broker, interfaceName);
- if (etreeInterface != null) {
- if (etreeInterface.getEtreeInterfaceType() == EtreeInterfaceType.Root) {
- EtreeLeafTagName etreeTagName = elanEtreeUtils.getEtreeLeafTagByElanTag(elanTag);
- if (etreeTagName == null) {
- LOG.warn("Interface " + interfaceName
- + " seems like it belongs to Etree but etreeTagName from elanTag " + elanTag + " is null.");
- } else {
- flowEntity = buildRemoteDmacFlowEntry(srcDpId, destDpId, lportTagOrVni,
- etreeTagName.getEtreeLeafTag().getValue(), macAddress, displayName, elanInstance);
- mdsalManager.addFlowToTx(srcDpId, flowEntity, writeFlowGroupTx);
- }
+ EtreeInterface etreeInterface = elanInterfaceCache.getEtreeInterface(interfaceName).orNull();
+ if (etreeInterface != null && etreeInterface.getEtreeInterfaceType() == EtreeInterfaceType.Root) {
+ EtreeLeafTagName etreeTagName = elanEtreeUtils.getEtreeLeafTagByElanTag(elanTag);
+ if (etreeTagName == null) {
+ LOG.warn("Interface {} seems like it belongs to Etree but etreeTagName from elanTag {} is null.",
+ interfaceName, elanTag);
+ } else {
+ flowEntity = buildRemoteDmacFlowEntry(srcDpId, destDpId, lportTagOrVni,
+ etreeTagName.getEtreeLeafTag().getValue(), macAddress, displayName, elanInstance);
+ mdsalManager.addFlowToTx(srcDpId, flowEntity, writeFlowGroupTx);
}
}
}
* macAddress
* @param displayName
* display Name
+ * @param elanInstance
+ * elanInstance
* @return the flow remote Dmac
- * @throws ElanException in case of issues creating the flow objects
*/
@SuppressWarnings("checkstyle:IllegalCatch")
public Flow buildRemoteDmacFlowEntry(BigInteger srcDpId, BigInteger destDpId, long lportTagOrVni, long elanTag,
- String macAddress, String displayName, ElanInstance elanInstance) throws ElanException {
+ String macAddress, String displayName, ElanInstance elanInstance) {
List<MatchInfo> mkMatches = new ArrayList<>();
mkMatches.add(new MatchMetadata(ElanHelper.getElanMetadataLabel(elanTag), MetaDataUtil.METADATA_MASK_SERVICE));
mkMatches.add(new MatchEthernetDestination(new MacAddress(macAddress)));
elanInstance);
}
actions = getEgressActionsForInterface(interfaceName, null);
- } else if (isVxlan(elanInstance)) {
+ } else if (isVxlanNetworkOrVxlanSegment(elanInstance)) {
actions = elanItmUtils.getInternalTunnelItmEgressAction(srcDpId, destDpId, lportTagOrVni);
}
mkInstructions.add(MDSALUtil.buildApplyActionsInstruction(actions));
} catch (Exception e) {
- LOG.error("Could not get egress actions to add to flow for srcDpId=" + srcDpId + ", destDpId=" + destDpId
- + ", lportTag/VNI=" + lportTagOrVni, e);
+ LOG.error("Could not get egress actions to add to flow for srcDpId {}, destDpId {}, lportTag/VNI {}",
+ srcDpId, destDpId, lportTagOrVni, e);
}
Flow flow = MDSALUtil.buildFlowNew(NwConstants.ELAN_DMAC_TABLE,
}
- public void deleteMacFlows(ElanInstance elanInfo, InterfaceInfo interfaceInfo, MacEntry macEntry,
- WriteTransaction deleteFlowGroupTx) {
+ public void deleteMacFlows(@Nullable ElanInstance elanInfo, @Nullable InterfaceInfo interfaceInfo,
+ MacEntry macEntry, WriteTransaction deleteFlowGroupTx) {
if (elanInfo == null || interfaceInfo == null) {
return;
}
* Updates the Elan information in the Operational DS. It also updates the
* ElanInstance in the Config DS by setting the adquired elanTag.
*
- * @param broker
- * the broker
* @param idManager
* the id manager
* @param elanInstanceAdded
*
* @return the updated ELAN instance.
*/
- public static ElanInstance updateOperationalDataStore(DataBroker broker, IdManagerService idManager,
+ public static ElanInstance updateOperationalDataStore(IdManagerService idManager,
ElanInstance elanInstanceAdded, List<String> elanInterfaces, WriteTransaction tx) {
String elanInstanceName = elanInstanceAdded.getElanInstanceName();
Long elanTag = elanInstanceAdded.getElanTag();
elanTag = retrieveNewElanTag(idManager, elanInstanceName);
}
Elan elanInfo = new ElanBuilder().setName(elanInstanceName).setElanInterfaces(elanInterfaces)
- .setKey(new ElanKey(elanInstanceName)).build();
+ .withKey(new ElanKey(elanInstanceName)).build();
// Add the ElanState in the elan-state operational data-store
tx.put(LogicalDatastoreType.OPERATIONAL, getElanInstanceOperationalDataPath(elanInstanceName),
elanInfo, WriteTransaction.CREATE_MISSING_PARENTS);
// Add the ElanMacTable in the elan-mac-table operational data-store
- MacTable elanMacTable = new MacTableBuilder().setKey(new MacTableKey(elanInstanceName)).build();
+ MacTable elanMacTable = new MacTableBuilder().withKey(new MacTableKey(elanInstanceName)).build();
tx.put(LogicalDatastoreType.OPERATIONAL, getElanMacTableOperationalDataPath(elanInstanceName),
elanMacTable, WriteTransaction.CREATE_MISSING_PARENTS);
ElanTagNameBuilder elanTagNameBuilder = new ElanTagNameBuilder().setElanTag(elanTag)
- .setKey(new ElanTagNameKey(elanTag)).setName(elanInstanceName);
+ .withKey(new ElanTagNameKey(elanTag)).setName(elanInstanceName);
long etreeLeafTag = -1;
if (isEtreeInstance(elanInstanceAdded)) {
etreeLeafTag = retrieveNewElanTag(idManager,elanInstanceName + ElanConstants
EtreeLeafTagName etreeLeafTagName = new EtreeLeafTagNameBuilder()
.setEtreeLeafTag(new EtreeLeafTag(etreeLeafTag)).build();
elanTagNameBuilder.addAugmentation(EtreeLeafTagName.class, etreeLeafTagName);
- addTheLeafTagAsElanTag(broker, elanInstanceName, etreeLeafTag, tx);
+ addTheLeafTagAsElanTag(elanInstanceName, etreeLeafTag, tx);
}
ElanTagName elanTagName = elanTagNameBuilder.build();
.setDescription(elanInstanceAdded.getDescription())
.setMacTimeout(elanInstanceAdded.getMacTimeout() == null
? Long.valueOf(ElanConstants.DEFAULT_MAC_TIME_OUT) : elanInstanceAdded.getMacTimeout())
- .setKey(elanInstanceAdded.getKey()).setElanTag(elanTag);
+ .withKey(elanInstanceAdded.key()).setElanTag(elanTag);
if (isEtreeInstance(elanInstanceAdded)) {
EtreeInstance etreeInstance = new EtreeInstanceBuilder().setEtreeLeafTagVal(new EtreeLeafTag(etreeLeafTag))
.build();
return elanInstanceWithTag;
}
- private static void addTheLeafTagAsElanTag(DataBroker broker, String elanInstanceName, long etreeLeafTag,
- WriteTransaction tx) {
+ private static void addTheLeafTagAsElanTag(String elanInstanceName, long etreeLeafTag, WriteTransaction tx) {
ElanTagName etreeTagAsElanTag = new ElanTagNameBuilder().setElanTag(etreeLeafTag)
- .setKey(new ElanTagNameKey(etreeLeafTag)).setName(elanInstanceName).build();
+ .withKey(new ElanTagNameKey(etreeLeafTag)).setName(elanInstanceName).build();
tx.put(LogicalDatastoreType.OPERATIONAL,
getElanInfoEntriesOperationalDataPath(etreeLeafTag), etreeTagAsElanTag);
}
private static boolean isEtreeInstance(ElanInstance elanInstanceAdded) {
- return elanInstanceAdded.getAugmentation(EtreeInstance.class) != null;
+ return elanInstanceAdded.augmentation(EtreeInstance.class) != null;
}
public boolean isDpnPresent(BigInteger dpnId) {
BigInteger cookie, List<Instruction> instructions) {
StypeOpenflowBuilder augBuilder = new StypeOpenflowBuilder().setFlowCookie(cookie).setFlowPriority(flowPriority)
.setInstruction(instructions);
- return new BoundServicesBuilder().setKey(new BoundServicesKey(servicePriority)).setServiceName(serviceName)
+ return new BoundServicesBuilder().withKey(new BoundServicesKey(servicePriority)).setServiceName(serviceName)
.setServicePriority(servicePriority).setServiceType(ServiceTypeFlowBased.class)
.addAugmentation(StypeOpenflow.class, augBuilder.build()).build();
}
public void removeTerminatingServiceAction(BigInteger destDpId, int serviceId) {
RemoveTerminatingServiceActionsInput input = new RemoveTerminatingServiceActionsInputBuilder()
.setDpnId(destDpId).setServiceId(serviceId).build();
- Future<RpcResult<Void>> futureObject = itmRpcService.removeTerminatingServiceActions(input);
+ Future<RpcResult<RemoveTerminatingServiceActionsOutput>> futureObject =
+ itmRpcService.removeTerminatingServiceActions(input);
try {
- RpcResult<Void> result = futureObject.get();
+ RpcResult<RemoveTerminatingServiceActionsOutput> result = futureObject.get();
if (result.isSuccessful()) {
LOG.debug("Successfully completed removeTerminatingServiceActions for ELAN with serviceId {} on "
+ "dpn {}", serviceId, destDpId);
}
} catch (InterruptedException | ExecutionException e) {
LOG.error("Error in RPC call removeTerminatingServiceActions for ELAN with serviceId {} on "
- + "dpn {}: {}", serviceId, destDpId, e);
+ + "dpn {}", serviceId, destDpId, e);
}
}
return idBuilder.build();
}
+ @CheckReturnValue
public static CheckedFuture<Void, TransactionCommitFailedException> waitForTransactionToComplete(
WriteTransaction tx) {
CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
try {
futures.get();
} catch (InterruptedException | ExecutionException e) {
- LOG.error("Error writing to datastore {}", e);
+ // NETVIRT-1215: Do not log.error() here, only debug(); but callers *MUST* @CheckReturnValue
+ LOG.debug("Error writing to datastore", e);
}
return futures;
}
- public static boolean isVxlanNetwork(DataBroker broker, String elanInstanceName) {
- ElanInstance elanInstance = getElanInstanceByName(broker, elanInstanceName);
- return elanInstance != null && isVxlan(elanInstance);
- }
-
- public static boolean isVxlan(ElanInstance elanInstance) {
+ public static boolean isVxlan(@Nullable ElanInstance elanInstance) {
return elanInstance != null && elanInstance.getSegmentType() != null
&& elanInstance.getSegmentType().isAssignableFrom(SegmentTypeVxlan.class)
&& elanInstance.getSegmentationId() != null && elanInstance.getSegmentationId() != 0;
public void addDmacRedirectToDispatcherFlows(Long elanTag, String displayName,
String macAddress, List<BigInteger> dpnIds) {
for (BigInteger dpId : dpnIds) {
- WriteTransaction writeTx = broker.newWriteOnlyTransaction();
- mdsalManager.addFlowToTx(buildDmacRedirectToDispatcherFlow(dpId, macAddress, displayName, elanTag),
- writeTx);
- writeTx.submit();
+ ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(
+ tx -> mdsalManager.addFlowToTx(
+ buildDmacRedirectToDispatcherFlow(dpId, macAddress, displayName, elanTag), tx)), LOG,
+ "Error adding DMAC redirect to dispatcher flows");
}
}
instructions.add(new InstructionApplyActions(actions));
String flowId = getKnownDynamicmacFlowRef(NwConstants.ELAN_DMAC_TABLE, dpId, dstMacAddress, elanTag);
- FlowEntity flow = MDSALUtil.buildFlowEntity(dpId, NwConstants.ELAN_DMAC_TABLE, flowId, 20, displayName, 0, 0,
+ return MDSALUtil.buildFlowEntity(dpId, NwConstants.ELAN_DMAC_TABLE, flowId, 20, displayName, 0, 0,
ElanConstants.COOKIE_ELAN_KNOWN_DMAC.add(BigInteger.valueOf(elanTag)),
matches, instructions);
- return flow;
- }
-
- /**
- * Add Mac Address to ElanInterfaceForwardingEntries and ElanForwardingTables
- * Install SMAC and DMAC flows.
- */
- public void addMacEntryToDsAndSetupFlows(String interfaceName,
- String macAddress, String elanName, WriteTransaction interfaceTx, WriteTransaction flowTx, int macTimeOut)
- throws ElanException {
- LOG.trace("Adding mac address {} and interface name {} to ElanInterfaceForwardingEntries and "
- + "ElanForwardingTables DS", macAddress, interfaceName);
- BigInteger timeStamp = new BigInteger(String.valueOf(System.currentTimeMillis()));
- PhysAddress physAddress = new PhysAddress(macAddress);
- MacEntry macEntry = new MacEntryBuilder().setInterface(interfaceName).setMacAddress(physAddress)
- .setKey(new MacEntryKey(physAddress)).setControllerLearnedForwardingEntryTimestamp(timeStamp)
- .setIsStaticAddress(false).build();
- InstanceIdentifier<MacEntry> macEntryId = ElanUtils
- .getInterfaceMacEntriesIdentifierOperationalDataPath(interfaceName, physAddress);
- interfaceTx.put(LogicalDatastoreType.OPERATIONAL, macEntryId, macEntry);
- InstanceIdentifier<MacEntry> elanMacEntryId = ElanUtils.getMacEntryOperationalDataPath(elanName, physAddress);
- interfaceTx.put(LogicalDatastoreType.OPERATIONAL, elanMacEntryId, macEntry);
- ElanInstance elanInstance = ElanUtils.getElanInstanceByName(broker, elanName);
- setupMacFlows(elanInstance, interfaceManager.getInterfaceInfo(interfaceName), macTimeOut, macAddress, true,
- flowTx);
- }
-
- /**
- * Remove Mac Address from ElanInterfaceForwardingEntries and ElanForwardingTables
- * Remove SMAC and DMAC flows.
- */
- public void deleteMacEntryFromDsAndRemoveFlows(String interfaceName,
- String macAddress, String elanName, WriteTransaction interfaceTx, WriteTransaction flowTx) {
- LOG.trace("Deleting mac address {} and interface name {} from ElanInterfaceForwardingEntries "
- + "and ElanForwardingTables DS", macAddress, interfaceName);
- PhysAddress physAddress = new PhysAddress(macAddress);
- MacEntry macEntry = getInterfaceMacEntriesOperationalDataPath(interfaceName, physAddress);
- InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
- if (macEntry != null && interfaceInfo != null) {
- deleteMacFlows(ElanUtils.getElanInstanceByName(broker, elanName), interfaceInfo, macEntry, flowTx);
- }
- interfaceTx.delete(LogicalDatastoreType.OPERATIONAL,
- ElanUtils.getInterfaceMacEntriesIdentifierOperationalDataPath(interfaceName, physAddress));
- interfaceTx.delete(LogicalDatastoreType.OPERATIONAL,
- ElanUtils.getMacEntryOperationalDataPath(elanName, physAddress));
}
public String getExternalElanInterface(String elanInstanceName, BigInteger dpnId) {
return elanMacKey.intern();
}
- // TODO This should return a collection of futures
- public static void addToListenableFutureIfTxException(RuntimeException exception,
- List<ListenableFuture<Void>> futures) {
+ public static List<ListenableFuture<Void>>
+ returnFailedListenableFutureIfTransactionCommitFailedExceptionCauseOrElseThrow(RuntimeException exception) {
+
Throwable cause = exception.getCause();
if (cause != null && cause instanceof TransactionCommitFailedException) {
- futures.add(Futures.immediateFailedCheckedFuture((TransactionCommitFailedException) cause));
+ return Collections.singletonList(Futures.immediateFailedFuture(cause));
+ } else {
+ throw exception;
}
}
return !isEmpty(collection);
}
- public static void setElanInstancToDpnsCache(Map<String, Set<DpnInterfaces>> elanInstancToDpnsCache) {
- ElanUtils.elanInstancToDpnsCache = elanInstancToDpnsCache;
- }
-
- public static Set<DpnInterfaces> getElanInvolvedDPNsFromCache(String elanName) {
- return elanInstancToDpnsCache.get(elanName);
- }
-
- public static void addDPNInterfaceToElanInCache(String elanName, DpnInterfaces dpnInterfaces) {
- elanInstancToDpnsCache.computeIfAbsent(elanName, key -> new HashSet<>()).add(dpnInterfaces);
- }
-
- public static void removeDPNInterfaceFromElanInCache(String elanName, DpnInterfaces dpnInterfaces) {
- elanInstancToDpnsCache.computeIfAbsent(elanName, key -> new HashSet<>()).remove(dpnInterfaces);
- }
-
public Optional<IpAddress> getSourceIpAddress(Ethernet ethernet) {
Optional<IpAddress> srcIpAddress = Optional.absent();
if (ethernet.getPayload() == null) {
org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
.ietf.interfaces.rev140508.interfaces.Interface configIface =
interfaceManager.getInterfaceInfoFromConfigDataStore(interfaceName);
- IfTunnel ifTunnel = configIface.getAugmentation(IfTunnel.class);
+ IfTunnel ifTunnel = configIface.augmentation(IfTunnel.class);
if (ifTunnel != null && ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeVxlan.class)) {
- ParentRefs refs = configIface.getAugmentation(ParentRefs.class);
+ ParentRefs refs = configIface.augmentation(ParentRefs.class);
if (refs != null && !Strings.isNullOrEmpty(refs.getParentInterface())) {
return true; //multiple VxLAN tunnels enabled, i.e. only logical tunnel should be treated
}
return false;
}
- public static void addElanInterfaceToElanInstanceCache(String elanInstanceName, String elanInterfaceName) {
- elanInstanceToInterfacesCache.computeIfAbsent(elanInstanceName, key -> new HashSet<>()).add(elanInterfaceName);
- }
-
- public static void removeElanInterfaceToElanInstanceCache(String elanInstanceName, String interfaceName) {
- Set<String> elanInterfaces = elanInstanceToInterfacesCache.get(elanInstanceName);
- if (elanInterfaces == null || elanInterfaces.isEmpty()) {
- return;
- }
- elanInterfaces.remove(interfaceName);
- }
-
- @Nonnull public static Set<String> removeAndGetElanInterfaces(String elanInstanceName) {
- Set<String> removed = elanInstanceToInterfacesCache.remove(elanInstanceName);
- return removed != null ? removed : Collections.emptySet();
- }
-
public static InstanceIdentifier<Flow> getFlowIid(Flow flow, BigInteger dpnId) {
FlowKey flowKey = new FlowKey(new FlowId(flow.getId()));
org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId nodeId =
new org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId("openflow:" + dpnId);
org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node nodeDpn =
- new NodeBuilder().setId(nodeId).setKey(new NodeKey(nodeId)).build();
+ new NodeBuilder().setId(nodeId).withKey(new NodeKey(nodeId)).build();
return InstanceIdentifier.builder(Nodes.class)
.child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class,
- nodeDpn.getKey()).augmentation(FlowCapableNode.class)
+ nodeDpn.key()).augmentation(FlowCapableNode.class)
.child(Table.class, new TableKey(flow.getTableId())).child(Flow.class, flowKey).build();
}
return "elaninterface-" + interfaceName;
}
- public void addArpResponderFlow(BigInteger dpnId, String ingressInterfaceName, String ipAddress, String macAddress,
- int lportTag, List<Instruction> instructions) {
- LOG.info("Installing the ARP responder flow on DPN {} for Interface {} with MAC {} & IP {}", dpnId,
- ingressInterfaceName, macAddress, ipAddress);
- ElanInterface elanIface = getElanInterfaceByElanInterfaceName(broker, ingressInterfaceName);
- ElanInstance elanInstance = getElanInstanceByName(broker, elanIface.getElanInstanceName());
- if (elanInstance == null) {
- LOG.debug("addArpResponderFlow: elanInstance is null, Failed to install arp responder flow for Interface {}"
- + " with MAC {} & IP {}", dpnId,
- ingressInterfaceName, macAddress, ipAddress);
- return;
- }
- String flowId = ArpResponderUtil.getFlowId(lportTag, ipAddress);
- ArpResponderUtil.installFlow(mdsalManager, dpnId, flowId, flowId, NwConstants.DEFAULT_ARP_FLOW_PRIORITY,
- ArpResponderUtil.generateCookie(lportTag, ipAddress),
- ArpResponderUtil.getMatchCriteria(lportTag, elanInstance, ipAddress), instructions);
- LOG.info("Installed the ARP Responder flow for Interface {}", ingressInterfaceName);
- }
-
- public void addExternalTunnelArpResponderFlow(BigInteger dpnId, String ipAddress, String macAddress,
- int lportTag, List<Instruction> instructions, String elanInstanceName) {
- LOG.trace("Installing the ExternalTunnel ARP responder flow on DPN {} for ElanInstance {} with MAC {} & IP {}",
- dpnId, elanInstanceName, macAddress, ipAddress);
- ElanInstance elanInstance = getElanInstanceByName(broker, elanInstanceName);
- String flowId = ArpResponderUtil.getFlowId(lportTag, ipAddress);
- ArpResponderUtil.installFlow(mdsalManager, dpnId, flowId, flowId, NwConstants.DEFAULT_ARP_FLOW_PRIORITY,
- ArpResponderUtil.generateCookie(lportTag, ipAddress),
- ArpResponderUtil.getMatchCriteria(lportTag, elanInstance, ipAddress), instructions);
- LOG.trace("Installed the ExternalTunnel ARP Responder flow for ElanInstance {}", elanInstanceName);
- }
-
public void removeArpResponderFlow(BigInteger dpnId, String ingressInterfaceName, String ipAddress,
int lportTag) {
LOG.info("Removing the ARP responder flow on DPN {} of Interface {} with IP {}", dpnId, ingressInterfaceName,
ipAddress);
ArpResponderUtil.removeFlow(mdsalManager, dpnId, ArpResponderUtil.getFlowId(lportTag, ipAddress));
}
+
+ public static String getRouterPordIdFromElanInstance(DataBroker dataBroker, String elanInstanceName) {
+ Optional<Subnetmaps> subnetMapsData =
+ read(dataBroker, LogicalDatastoreType.CONFIGURATION, buildSubnetMapsWildCardPath());
+ if (subnetMapsData.isPresent()) {
+ List<Subnetmap> subnetMapList = subnetMapsData.get().getSubnetmap();
+ if (subnetMapList != null && !subnetMapList.isEmpty()) {
+ for (Subnetmap subnet : subnetMapList) {
+ if (subnet.getNetworkId().getValue().equals(elanInstanceName)) {
+ if (subnet.getRouterInterfacePortId() != null) {
+ return subnet.getRouterInterfacePortId().getValue();
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ static InstanceIdentifier<Subnetmaps> buildSubnetMapsWildCardPath() {
+ return InstanceIdentifier.create(Subnetmaps.class);
+ }
}