import org.opendaylight.genius.mdsalutil.ActionInfo;
import org.opendaylight.genius.mdsalutil.BucketInfo;
import org.opendaylight.genius.mdsalutil.FlowEntity;
-import org.opendaylight.genius.mdsalutil.GroupEntity;
import org.opendaylight.genius.mdsalutil.InstructionInfo;
import org.opendaylight.genius.mdsalutil.MDSALUtil;
import org.opendaylight.genius.mdsalutil.MatchInfo;
import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldEthernetSource;
import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
-import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
import org.opendaylight.genius.mdsalutil.matches.MatchArpOp;
import org.opendaylight.genius.mdsalutil.matches.MatchArpTpa;
import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
import org.opendaylight.netvirt.elanmanager.api.ElanHelper;
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.action.types.rev131112.action.list.Action;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
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.itm.rpcs.rev160406.GetEgressActionsForTunnelInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionResubmitRpcAddGroupCase;
import org.opendaylight.yangtools.yang.common.RpcResult;
private ArpResponderUtil() {
}
- /**
- * Install Group flow on the DPN.
- *
- * @param mdSalManager
- * Reference of MDSAL API RPC that provides API for installing
- * group flow
- * @param dpnId
- * DPN on which group flow to be installed
- * @param groupdId
- * Uniquely identifiable Group Id for the group flow
- * @param groupName
- * Name of the group flow
- * @param buckets
- * List of the bucket actions for the group flow
- */
- public static void installGroup(IMdsalApiManager mdSalManager, BigInteger dpnId, long groupdId, String groupName,
- List<BucketInfo> buckets) {
- LOG.trace("Installing group flow on dpn {}", dpnId);
- GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupdId, groupName, GroupTypes.GroupAll, buckets);
- mdSalManager.syncInstallGroup(groupEntity);
- }
-
/**
* Get Default ARP Responder Drop flow on the DPN.
*
* @return List of bucket actions
*/
public static List<BucketInfo> getDefaultBucketInfos(short resubmitTableId) {
- return Arrays.asList(
- new BucketInfo(Collections.singletonList(new ActionNxResubmit(resubmitTableId))));
+ return Collections.singletonList(
+ new BucketInfo(Collections.singletonList(new ActionNxResubmit(resubmitTableId))));
}
/**
* MacAddress for which ARP Response packet is to be generated
* @return List of ARP Responder Actions actions
*/
- public static List<Action> getActions(IInterfaceManager ifaceMgrRpcService, ItmRpcService itmRpcService,
- String ifName, String ipAddress, String macAddress,
- boolean isTunnelInterface) {
+ private static List<Action> getActions(IInterfaceManager ifaceMgrRpcService, ItmRpcService itmRpcService,
+ String ifName, String ipAddress, String macAddress,
+ boolean isTunnelInterface) {
AtomicInteger actionCounter = new AtomicInteger();
List<Action> actions = arpActions.apply(actionCounter, macAddress, ipAddress);
return instructions;
}
- /**
- * Install ARP Responder FLOW.
- *
- * @param mdSalManager
- * Reference of MDSAL API RPC that provides API for installing
- * flow
- * @param dpnId
- * DPN on which flow to be installed
- * @param flowId
- * Uniquely Identifiable Arp Responder Table flow Id
- * @param flowName
- * Readable flow name
- * @param priority
- * Flow Priority
- * @param cookie
- * Flow Cookie
- * @param matches
- * List of Match Criteria for the flow
- * @param instructions
- * List of Instructions for the flow
- */
- public static void installFlow(IMdsalApiManager mdSalManager, BigInteger dpnId, String flowId, String flowName,
- int priority, BigInteger cookie, List<MatchInfo> matches, List<Instruction> instructions) {
- Flow flowEntity = MDSALUtil.buildFlowNew(NwConstants.ARP_RESPONDER_TABLE, flowId, priority, flowName, 0, 0,
- cookie, matches, instructions);
- mdSalManager.installFlow(dpnId, flowEntity);
- }
-
- /**
- * Remove flow form DPN.
- *
- * @param mdSalManager
- * Reference of MDSAL API RPC that provides API for installing
- * flow
- * @param dpnId
- * DPN form which flow to be removed
- * @param flowId
- * Uniquely Identifiable Arp Responder Table flow Id that is to
- * be removed
- */
- public static void removeFlow(IMdsalApiManager mdSalManager, BigInteger dpnId, String flowId) {
- Flow flowEntity = MDSALUtil.buildFlow(NwConstants.ARP_RESPONDER_TABLE, flowId);
- mdSalManager.removeFlow(dpnId, flowEntity);
- }
-
/**
* Creates Uniquely Identifiable flow Id.
*
package org.opendaylight.netvirt.elan.evpn.listeners;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+
+import java.util.concurrent.ExecutionException;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
import org.opendaylight.netvirt.elan.evpn.utils.EvpnMacVrfUtils;
import org.opendaylight.netvirt.elan.evpn.utils.EvpnUtils;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
public class EvpnElanInstanceListener extends AsyncDataTreeChangeListenerBase<ElanInstance, EvpnElanInstanceListener> {
private static final Logger LOG = LoggerFactory.getLogger(EvpnElanInstanceListener.class);
private final DataBroker broker;
+ private final ManagedNewTransactionRunner txRunner;
private final EvpnUtils evpnUtils;
private final EvpnMacVrfUtils evpnMacVrfUtils;
private final IMdsalApiManager mdsalManager;
EvpnMacVrfUtils evpnMacVrfUtils, IMdsalApiManager mdsalApiManager) {
super(ElanInstance.class, EvpnElanInstanceListener.class);
this.broker = dataBroker;
+ this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
this.evpnUtils = evpnUtils;
this.evpnMacVrfUtils = evpnMacVrfUtils;
this.mdsalManager = mdsalApiManager;
protected void update(InstanceIdentifier<ElanInstance> instanceIdentifier, ElanInstance original,
ElanInstance update) {
String elanName = update.getElanInstanceName();
- if (evpnUtils.isWithdrawEvpnRT2Routes(original, update)) {
- evpnUtils.withdrawEvpnRT2Routes(original.augmentation(EvpnAugmentation.class), elanName);
- evpnMacVrfUtils.updateEvpnDmacFlows(original, false);
- evpnUtils.programEvpnL2vniDemuxTable(elanName,
- (elan, interfaceName) -> evpnUtils.bindElanServiceToExternalTunnel(elanName, interfaceName),
- mdsalManager::installFlow);
- } else if (evpnUtils.isAdvertiseEvpnRT2Routes(original, update)) {
- evpnUtils.advertiseEvpnRT2Routes(update.augmentation(EvpnAugmentation.class), elanName);
- evpnMacVrfUtils.updateEvpnDmacFlows(update, true);
- evpnUtils.programEvpnL2vniDemuxTable(elanName,
- (elan, interfaceName) -> evpnUtils.unbindElanServiceFromExternalTunnel(elanName, interfaceName),
- mdsalManager::removeFlow);
- }
+ ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, confTx -> {
+ if (evpnUtils.isWithdrawEvpnRT2Routes(original, update)) {
+ evpnUtils.withdrawEvpnRT2Routes(original.augmentation(EvpnAugmentation.class), elanName);
+ evpnMacVrfUtils.updateEvpnDmacFlows(original, false);
+ evpnUtils.programEvpnL2vniDemuxTable(elanName,
+ (elan, interfaceName) -> evpnUtils.bindElanServiceToExternalTunnel(elanName, interfaceName),
+ (dpnId, flowEntity) -> mdsalManager.addFlow(confTx, flowEntity));
+ } else if (evpnUtils.isAdvertiseEvpnRT2Routes(original, update)) {
+ evpnUtils.advertiseEvpnRT2Routes(update.augmentation(EvpnAugmentation.class), elanName);
+ evpnMacVrfUtils.updateEvpnDmacFlows(update, true);
+ evpnUtils.programEvpnL2vniDemuxTable(elanName,
+ (elan, interfaceName) -> evpnUtils.unbindElanServiceFromExternalTunnel(elanName, interfaceName),
+ (dpnId, flowEntity) -> {
+ try {
+ mdsalManager.removeFlow(confTx, dpnId, flowEntity.getFlowId(), flowEntity.getTableId());
+ } catch (ExecutionException | InterruptedException e) {
+ LOG.error("Error removing flow", e);
+ }
+ });
+ }
+ }), LOG, "Error handling EVPN ELAN instance update");
}
@Override
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.genius.infra.Datastore;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.genius.mdsalutil.MDSALUtil;
import org.opendaylight.genius.mdsalutil.MatchInfo;
import org.opendaylight.genius.mdsalutil.NwConstants;
private final IMdsalApiManager mdsalManager;
private final ElanItmUtils elanItmUtils;
private final ElanEtreeUtils elanEtreeUtils;
+ private final ManagedNewTransactionRunner txRunner;
@Inject
public ElanEvpnFlowUtils(final IMdsalApiManager mdsalManager, final ElanItmUtils elanItmUtils,
- final ElanEtreeUtils elanEtreeUtils) {
+ final ElanEtreeUtils elanEtreeUtils, final DataBroker dataBroker) {
this.mdsalManager = mdsalManager;
this.elanItmUtils = elanItmUtils;
this.elanEtreeUtils = elanEtreeUtils;
+ this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
}
public Flow evpnBuildDmacFlowForExternalRemoteMac(EvpnDmacFlow evpnDmacFlow) {
String flowId = ElanEvpnFlowUtils.evpnGetKnownDynamicmacFlowRef(NwConstants.ELAN_DMAC_TABLE, dpId, nexthopIp,
macToRemove, elanTag, true);
Flow flowToRemove = new FlowBuilder().setId(new FlowId(flowId)).setTableId(NwConstants.ELAN_DMAC_TABLE).build();
- return Collections.singletonList(mdsalManager.removeFlow(dpId, flowToRemove));
+ return Collections.singletonList(txRunner.callWithNewReadWriteTransactionAndSubmit(Datastore.CONFIGURATION,
+ tx -> mdsalManager.removeFlow(tx, dpId, flowToRemove)));
}
private List<ListenableFuture<Void>> evpnRemoveFlowThatSendsThePacketOnAnExternalTunnel(long elanTag,
String flowId = ElanEvpnFlowUtils.evpnGetKnownDynamicmacFlowRef(NwConstants.ELAN_DMAC_TABLE, dpId, nexthopIp,
macToRemove, elanTag, false);
Flow flowToRemove = new FlowBuilder().setId(new FlowId(flowId)).setTableId(NwConstants.ELAN_DMAC_TABLE).build();
- return Collections.singletonList(mdsalManager.removeFlow(dpId, flowToRemove));
+ return Collections.singletonList(txRunner.callWithNewReadWriteTransactionAndSubmit(Datastore.CONFIGURATION,
+ tx -> mdsalManager.removeFlow(tx, dpId, flowToRemove)));
}
public static class EvpnDmacFlowBuilder {
import com.google.common.util.concurrent.ListenableFuture;
import java.math.BigInteger;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;
import javax.inject.Inject;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.genius.infra.Datastore;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
import org.opendaylight.netvirt.elan.cache.ElanInstanceCache;
private static final Logger LOG = LoggerFactory.getLogger(EvpnMacVrfUtils.class);
private final DataBroker dataBroker;
+ private final ManagedNewTransactionRunner txRunner;
private final IdManagerService idManager;
private final ElanEvpnFlowUtils elanEvpnFlowUtils;
private final IMdsalApiManager mdsalManager;
final ElanEvpnFlowUtils elanEvpnFlowUtils, final IMdsalApiManager mdsalManager, final EvpnUtils evpnUtils,
final JobCoordinator jobCoordinator, final ElanUtils elanUtils, final ElanInstanceCache elanInstanceCache) {
this.dataBroker = dataBroker;
+ this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
this.idManager = idManager;
this.elanEvpnFlowUtils = elanEvpnFlowUtils;
this.mdsalManager = mdsalManager;
String dstMacAddress = macVrfEntry.getMac();
long vni = macVrfEntry.getL2vni();
- jobCoordinator.enqueueJob(dstMacAddress, () -> {
- List<ListenableFuture<Void>> futures = new ArrayList<>();
- dpnInterfaceLists.forEach(dpnInterfaces -> {
- BigInteger dpId = dpnInterfaces.getDpId();
- LOG.info("ADD: Build DMAC flow with dpId {}, nexthopIP {}, elanTag {},"
- + "vni {}, dstMacAddress {}, elanName {} ",
+ jobCoordinator.enqueueJob(dstMacAddress, () -> Collections.singletonList(
+ txRunner.callWithNewWriteOnlyTransactionAndSubmit(Datastore.CONFIGURATION,
+ tx -> dpnInterfaceLists.forEach(dpnInterfaces -> {
+ BigInteger dpId = dpnInterfaces.getDpId();
+ LOG.info("ADD: Build DMAC flow with dpId {}, nexthopIP {}, elanTag {},"
+ + "vni {}, dstMacAddress {}, elanName {} ",
dpId, nexthopIP, elanTag, vni, dstMacAddress, elanName);
- ElanEvpnFlowUtils.EvpnDmacFlowBuilder dmacFlowBuilder = new ElanEvpnFlowUtils.EvpnDmacFlowBuilder();
- dmacFlowBuilder.setDpId(dpId).setNexthopIP(ipAddress.toString()).setElanTag(elanTag).setVni(vni)
+ ElanEvpnFlowUtils.EvpnDmacFlowBuilder dmacFlowBuilder =
+ new ElanEvpnFlowUtils.EvpnDmacFlowBuilder();
+ dmacFlowBuilder.setDpId(dpId).setNexthopIP(ipAddress.toString()).setElanTag(elanTag).setVni(
+ vni)
.setDstMacAddress(dstMacAddress).setElanName(elanName);
- Flow flow = elanEvpnFlowUtils.evpnBuildDmacFlowForExternalRemoteMac(dmacFlowBuilder.build());
+ Flow flow =
+ elanEvpnFlowUtils.evpnBuildDmacFlowForExternalRemoteMac(dmacFlowBuilder.build());
- futures.add(mdsalManager.installFlow(dpId, flow));
- });
- return futures;
- }, ElanConstants.JOB_MAX_RETRIES);
+ mdsalManager.addFlow(tx, dpId, flow);
+ }))), ElanConstants.JOB_MAX_RETRIES);
}
}
Long elanTag = elanInstance.getElanTag();
String dstMacAddress = macVrfEntry.getMac();
long vni = macVrfEntry.getL2vni();
- jobCoordinator.enqueueJob(dstMacAddress, () -> {
- List<ListenableFuture<Void>> futures = new ArrayList<>();
- dpnInterfaceLists.forEach(dpnInterfaces -> {
- BigInteger dpId = dpnInterfaces.getDpId();
- LOG.info("ADD: Build DMAC flow with dpId {}, nexthopIP {}, elanTag {},"
- + "vni {}, dstMacAddress {}, elanName {} ",
+ jobCoordinator.enqueueJob(dstMacAddress, () -> Collections.singletonList(
+ txRunner.callWithNewWriteOnlyTransactionAndSubmit(Datastore.CONFIGURATION,
+ tx -> dpnInterfaceLists.forEach(dpnInterfaces -> {
+ BigInteger dpId = dpnInterfaces.getDpId();
+ LOG.info("ADD: Build DMAC flow with dpId {}, nexthopIP {}, elanTag {},"
+ + "vni {}, dstMacAddress {}, elanName {} ",
dpId, nexthopIP, elanTag, vni, dstMacAddress, elanName);
- ElanEvpnFlowUtils.EvpnDmacFlowBuilder dmacFlowBuilder = new ElanEvpnFlowUtils.EvpnDmacFlowBuilder();
- dmacFlowBuilder.setDpId(dpId).setNexthopIP(ipAddress.toString()).setElanTag(elanTag).setVni(vni)
+ ElanEvpnFlowUtils.EvpnDmacFlowBuilder dmacFlowBuilder =
+ new ElanEvpnFlowUtils.EvpnDmacFlowBuilder();
+ dmacFlowBuilder.setDpId(dpId).setNexthopIP(ipAddress.toString()).setElanTag(elanTag).setVni(vni)
.setDstMacAddress(dstMacAddress).setElanName(elanName);
- Flow flow = elanEvpnFlowUtils.evpnBuildDmacFlowForExternalRemoteMac(dmacFlowBuilder.build());
- futures.add(mdsalManager.installFlow(dpId, flow));
- });
- return futures;
- }, ElanConstants.JOB_MAX_RETRIES);
+ Flow flow = elanEvpnFlowUtils.evpnBuildDmacFlowForExternalRemoteMac(dmacFlowBuilder.build());
+ mdsalManager.addFlow(tx, dpId, flow);
+ }))), ElanConstants.JOB_MAX_RETRIES);
}
}
*/
package org.opendaylight.netvirt.elan.internal;
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.SettableFuture;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+
+import java.util.Collections;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
import org.opendaylight.netvirt.elan.cache.ElanInstanceCache;
import org.opendaylight.netvirt.elan.l2gw.utils.ElanL2GatewayMulticastUtils;
private static final Logger LOG = LoggerFactory.getLogger(ElanExtnTepListener.class);
private final DataBroker broker;
+ private final ManagedNewTransactionRunner txRunner;
private final ElanL2GatewayMulticastUtils elanL2GatewayMulticastUtils;
private final JobCoordinator jobCoordinator;
private final ElanInstanceCache elanInstanceCache;
JobCoordinator jobCoordinator, ElanInstanceCache elanInstanceCache) {
super(ExternalTeps.class, ElanExtnTepListener.class);
this.broker = dataBroker;
+ this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
this.elanL2GatewayMulticastUtils = elanL2GatewayMulticastUtils;
this.jobCoordinator = jobCoordinator;
this.elanInstanceCache = elanInstanceCache;
return;
}
- jobCoordinator.enqueueJob(elanName, () -> {
- SettableFuture<Void> ft = SettableFuture.create();
- try {
- //TODO make the following method return ft
- elanL2GatewayMulticastUtils.updateRemoteBroadcastGroupForAllElanDpns(elanInfo);
- ft.set(null);
- } catch (Exception e) {
- //since the above method does a sync write , if it fails there was no retry
- //by setting the above mdsal exception in ft, and returning the ft makes sures that job is retried
- ft.setException(e);
- }
- return Lists.newArrayList(ft);
- }, ElanConstants.JOB_MAX_RETRIES);
+ jobCoordinator.enqueueJob(elanName,
+ () -> Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+ confTx -> elanL2GatewayMulticastUtils.updateRemoteBroadcastGroupForAllElanDpns(elanInfo, confTx))),
+ ElanConstants.JOB_MAX_RETRIES);
}
@Override
elanUtils.removeTerminatingServiceAction(holder.dpId,
ElanUtils.getVxlanSegmentationId(elanInfo).intValue());
}
- unsetExternalTunnelTable(holder.dpId, elanInfo);
+ unsetExternalTunnelTable(holder.dpId, elanInfo, flowTx);
}
holder.isLastInterfaceOnDpn = true;
} else {
- setupLocalBroadcastGroups(elanInfo, dpnInterfaces, interfaceInfo);
+ setupLocalBroadcastGroups(elanInfo, dpnInterfaces, interfaceInfo, flowTx);
}
}
}));
futures.forEach(ElanUtils::waitForTransactionToComplete);
if (holder.isLastInterfaceOnDpn && holder.dpId != null && isVxlanNetworkOrVxlanSegment(elanInfo)) {
- setElanAndEtreeBCGrouponOtherDpns(elanInfo, holder.dpId);
+ futures.add(
+ ElanUtils.waitForTransactionToComplete(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+ confTx -> setElanAndEtreeBCGrouponOtherDpns(elanInfo, holder.dpId, confTx))));
}
InterfaceRemoveWorkerOnElanInterface removeInterfaceWorker = new InterfaceRemoveWorkerOnElanInterface(
interfaceName, elanInfo, interfaceInfo, this, holder.isLastElanInterface);
private void deleteAllRemoteMacsInADpn(String elanName, BigInteger dpId, long elanTag) {
List<DpnInterfaces> dpnInterfaces = elanUtils.getInvolvedDpnsInElan(elanName);
- for (DpnInterfaces dpnInterface : dpnInterfaces) {
- BigInteger currentDpId = dpnInterface.getDpId();
- if (!currentDpId.equals(dpId)) {
- for (String elanInterface : dpnInterface.getInterfaces()) {
- ElanInterfaceMac macs = elanUtils.getElanInterfaceMacByInterfaceName(elanInterface);
- if (macs == null || macs.getMacEntry() == null) {
- continue;
- }
- for (MacEntry mac : macs.getMacEntry()) {
- removeTheMacFlowInTheDPN(dpId, elanTag, currentDpId, mac);
- removeEtreeMacFlowInTheDPN(dpId, elanTag, currentDpId, mac);
+ ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, confTx -> {
+ for (DpnInterfaces dpnInterface : dpnInterfaces) {
+ BigInteger currentDpId = dpnInterface.getDpId();
+ if (!currentDpId.equals(dpId)) {
+ for (String elanInterface : dpnInterface.getInterfaces()) {
+ ElanInterfaceMac macs = elanUtils.getElanInterfaceMacByInterfaceName(elanInterface);
+ if (macs == null || macs.getMacEntry() == null) {
+ continue;
+ }
+ for (MacEntry mac : macs.getMacEntry()) {
+ removeTheMacFlowInTheDPN(dpId, elanTag, currentDpId, mac, confTx);
+ removeEtreeMacFlowInTheDPN(dpId, elanTag, currentDpId, mac, confTx);
+ }
}
}
}
- }
+ }), LOG, "Error deleting remote MACs in DPN {}", dpId);
}
- private void removeEtreeMacFlowInTheDPN(BigInteger dpId, long elanTag, BigInteger currentDpId, MacEntry mac) {
+ private void removeEtreeMacFlowInTheDPN(BigInteger dpId, long elanTag, BigInteger currentDpId, MacEntry mac,
+ TypedReadWriteTransaction<Configuration> confTx) throws ExecutionException, InterruptedException {
EtreeLeafTagName etreeLeafTag = elanEtreeUtils.getEtreeLeafTagByElanTag(elanTag);
if (etreeLeafTag != null) {
- removeTheMacFlowInTheDPN(dpId, etreeLeafTag.getEtreeLeafTag().getValue(), currentDpId, mac);
+ removeTheMacFlowInTheDPN(dpId, etreeLeafTag.getEtreeLeafTag().getValue(), currentDpId, mac, confTx);
}
}
- private void removeTheMacFlowInTheDPN(BigInteger dpId, long elanTag, BigInteger currentDpId, MacEntry mac) {
+ private void removeTheMacFlowInTheDPN(BigInteger dpId, long elanTag, BigInteger currentDpId, MacEntry mac,
+ TypedReadWriteTransaction<Configuration> confTx) throws ExecutionException, InterruptedException {
mdsalManager
- .removeFlow(dpId,
+ .removeFlow(confTx, dpId,
MDSALUtil.buildFlow(NwConstants.ELAN_DMAC_TABLE,
ElanUtils.getKnownDynamicmacFlowRef(NwConstants.ELAN_DMAC_TABLE, dpId, currentDpId,
mac.getMacAddress().getValue(), elanTag)));
// The 1st ElanInterface in a DPN must program the Ext Tunnel
// table, but only if Elan has VNI
if (isVxlanNetworkOrVxlanSegment(elanInstance)) {
- setExternalTunnelTable(holder.dpId, elanInstance);
+ futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+ confTx -> setExternalTunnelTable(holder.dpId, elanInstance, confTx)));
}
elanL2GatewayUtils.installElanL2gwDevicesLocalMacsInDpn(holder.dpId, elanInstance,
interfaceName);
createElanInterfaceTablesList(interfaceName, operTx);
}));
futures.forEach(ElanUtils::waitForTransactionToComplete);
- installEntriesForFirstInterfaceonDpn(elanInstance, interfaceInfo, holder.dpnInterfaces,
- holder.isFirstInterfaceInDpn);
+ futures.add(
+ ElanUtils.waitForTransactionToComplete(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+ confTx -> installEntriesForFirstInterfaceonDpn(elanInstance, interfaceInfo, holder.dpnInterfaces,
+ holder.isFirstInterfaceInDpn, confTx))));
// add the vlan provider interface to remote BC group for the elan
// for internal vlan networks
//update the remote-DPNs remoteBC group entry with Tunnels
LOG.trace("update remote bc group for elan {} on other DPNs for newly added dpn {}", elanInstance,
holder.dpId);
- setElanAndEtreeBCGrouponOtherDpns(elanInstance, holder.dpId);
+ futures.add(
+ ElanUtils.waitForTransactionToComplete(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+ confTx -> setElanAndEtreeBCGrouponOtherDpns(elanInstance, holder.dpId, confTx))));
}
String jobKey = ElanUtils.getElanInterfaceJobKey(interfaceName);
bindService(elanInstance, elanInterface, interfaceInfo.getInterfaceTag(), confTx);
}
- public void installEntriesForFirstInterfaceonDpn(ElanInstance elanInfo, InterfaceInfo interfaceInfo,
- DpnInterfaces dpnInterfaces, boolean isFirstInterfaceInDpn) {
+ private void installEntriesForFirstInterfaceonDpn(ElanInstance elanInfo, InterfaceInfo interfaceInfo,
+ DpnInterfaces dpnInterfaces, boolean isFirstInterfaceInDpn, TypedWriteTransaction<Configuration> confTx) {
if (!isOperational(interfaceInfo)) {
return;
}
// LocalBroadcast Group creation with elan-Interfaces
- setupLocalBroadcastGroups(elanInfo, dpnInterfaces, interfaceInfo);
+ setupLocalBroadcastGroups(elanInfo, dpnInterfaces, interfaceInfo, confTx);
if (isFirstInterfaceInDpn) {
LOG.trace("waitTimeForSyncInstall is {}", WAIT_TIME_FOR_SYNC_INSTALL);
BigInteger dpId = interfaceInfo.getDpId();
} catch (InterruptedException e1) {
LOG.warn("Error while waiting for local BC group for ELAN {} to install", elanInfo);
}
- elanL2GatewayMulticastUtils.setupElanBroadcastGroups(elanInfo, dpnInterfaces, dpId);
+ elanL2GatewayMulticastUtils.setupElanBroadcastGroups(elanInfo, dpnInterfaces, dpId, confTx);
try {
Thread.sleep(WAIT_TIME_FOR_SYNC_INSTALL);
} catch (InterruptedException e1) {
mdsalManager.removeFlow(flowTx, interfaceInfo.getDpId(), flowEntity);
}
- private void setElanAndEtreeBCGrouponOtherDpns(ElanInstance elanInfo, BigInteger dpId) {
+ private void setElanAndEtreeBCGrouponOtherDpns(ElanInstance elanInfo, BigInteger dpId,
+ TypedWriteTransaction<Configuration> confTx) {
int elanTag = elanInfo.getElanTag().intValue();
long groupId = ElanUtils.getElanRemoteBCGId(elanTag);
- setBCGrouponOtherDpns(elanInfo, dpId, elanTag, groupId);
+ setBCGrouponOtherDpns(elanInfo, dpId, elanTag, groupId, confTx);
EtreeInstance etreeInstance = elanInfo.augmentation(EtreeInstance.class);
if (etreeInstance != null) {
int etreeLeafTag = etreeInstance.getEtreeLeafTagVal().getValue().intValue();
long etreeLeafGroupId = ElanUtils.getEtreeLeafRemoteBCGId(etreeLeafTag);
- setBCGrouponOtherDpns(elanInfo, dpId, etreeLeafTag, etreeLeafGroupId);
+ setBCGrouponOtherDpns(elanInfo, dpId, etreeLeafTag, etreeLeafGroupId, confTx);
}
}
@SuppressWarnings("checkstyle:IllegalCatch")
- private void setBCGrouponOtherDpns(ElanInstance elanInfo, BigInteger dpId, int elanTag, long groupId) {
+ private void setBCGrouponOtherDpns(ElanInstance elanInfo, BigInteger dpId, int elanTag, long groupId,
+ TypedWriteTransaction<Configuration> confTx) {
int bucketId = 0;
ElanDpnInterfacesList elanDpns = elanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
if (elanDpns != null) {
Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll,
MDSALUtil.buildBucketLists(remoteListBucketInfo));
LOG.trace("Installing remote bc group {} on dpnId {}", group, dpnInterface.getDpId());
- mdsalManager.syncInstallGroup(dpnInterface.getDpId(), group);
+ mdsalManager.addGroup(confTx, dpnInterface.getDpId(), group);
}
}
try {
}
// Install DMAC entry on dst DPN
- @SuppressWarnings("checkstyle:ForbidCertainMethod")
public List<ListenableFuture<Void>> installDMacAddressTables(ElanInstance elanInfo, InterfaceInfo interfaceInfo,
BigInteger dstDpId) {
String interfaceName = interfaceInfo.getInterfaceName();
listBucket.add(dropBucket);
}
- public void setupLocalBroadcastGroups(ElanInstance elanInfo, DpnInterfaces newDpnInterface,
- InterfaceInfo interfaceInfo) {
- setupStandardLocalBroadcastGroups(elanInfo, newDpnInterface, interfaceInfo);
- setupLeavesLocalBroadcastGroups(elanInfo, newDpnInterface, interfaceInfo);
+ private void setupLocalBroadcastGroups(ElanInstance elanInfo, DpnInterfaces newDpnInterface,
+ InterfaceInfo interfaceInfo, TypedWriteTransaction<Configuration> confTx) {
+ setupStandardLocalBroadcastGroups(elanInfo, newDpnInterface, interfaceInfo, confTx);
+ setupLeavesLocalBroadcastGroups(elanInfo, newDpnInterface, interfaceInfo, confTx);
}
- public void setupStandardLocalBroadcastGroups(ElanInstance elanInfo, DpnInterfaces newDpnInterface,
- InterfaceInfo interfaceInfo) {
+ private void setupStandardLocalBroadcastGroups(ElanInstance elanInfo, DpnInterfaces newDpnInterface,
+ InterfaceInfo interfaceInfo, TypedWriteTransaction<Configuration> confTx) {
List<Bucket> listBucket = new ArrayList<>();
int bucketId = 0;
long groupId = ElanUtils.getElanLocalBCGId(elanInfo.getElanTag());
Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll,
MDSALUtil.buildBucketLists(listBucket));
LOG.trace("installing the localBroadCast Group:{}", group);
- mdsalManager.syncInstallGroup(interfaceInfo.getDpId(), group);
+ mdsalManager.addGroup(confTx, interfaceInfo.getDpId(), group);
}
private void setupLeavesLocalBroadcastGroups(ElanInstance elanInfo, DpnInterfaces newDpnInterface,
- InterfaceInfo interfaceInfo) {
+ InterfaceInfo interfaceInfo, TypedWriteTransaction<Configuration> confTx) {
EtreeInstance etreeInstance = elanInfo.augmentation(EtreeInstance.class);
if (etreeInstance != null) {
List<Bucket> listBucket = new ArrayList<>();
Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll,
MDSALUtil.buildBucketLists(listBucket));
LOG.trace("installing the localBroadCast Group:{}", group);
- mdsalManager.syncInstallGroup(interfaceInfo.getDpId(), group);
+ mdsalManager.addGroup(confTx, interfaceInfo.getDpId(), group);
}
}
* Installs a flow in the External Tunnel table consisting in translating
* the VNI retrieved from the packet that came over a tunnel with a TOR into
* elanTag that will be used later in the ELANs pipeline.
- *
- * @param dpnId
- * the dpn id
- * @param elanInfo
- * the elan info
+ * @param dpnId the dpn id
*/
- public void setExternalTunnelTable(BigInteger dpnId, ElanInstance elanInfo) {
+ private void setExternalTunnelTable(BigInteger dpnId, ElanInstance elanInfo,
+ TypedWriteTransaction<Configuration> confTx) {
long elanTag = elanInfo.getElanTag();
FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpnId, NwConstants.EXTERNAL_TUNNEL_TABLE,
getFlowRef(NwConstants.EXTERNAL_TUNNEL_TABLE, elanTag), 5, // prio
buildMatchesForVni(ElanUtils.getVxlanSegmentationId(elanInfo)),
getInstructionsIntOrExtTunnelTable(elanTag));
- mdsalManager.installFlow(flowEntity);
+ mdsalManager.addFlow(confTx, flowEntity);
}
/**
* elanTag. Important: ensure this method is only called whenever there is
* no other ElanInterface in the specified DPN
*
- * @param dpnId
- * DPN whose Ext Tunnel table is going to be modified
- * @param elanInfo
- * holds the elanTag needed for selecting the flow to be removed
+ * @param dpnId DPN whose Ext Tunnel table is going to be modified
*/
- public void unsetExternalTunnelTable(BigInteger dpnId, ElanInstance elanInfo) {
+ private void unsetExternalTunnelTable(BigInteger dpnId, ElanInstance elanInfo,
+ TypedReadWriteTransaction<Configuration> confTx) throws ExecutionException, InterruptedException {
// TODO: Use DataStoreJobCoordinator in order to avoid that removing the
// last ElanInstance plus
// adding a new one does (almost at the same time) are executed in that
.setTableId(NwConstants.EXTERNAL_TUNNEL_TABLE)
.setFlowId(flowId)
.build();
- mdsalManager.removeFlow(flowEntity);
+ mdsalManager.removeFlow(confTx, flowEntity);
}
public void setupTerminateServiceTable(ElanInstance elanInfo, BigInteger dpId,
// update Remote BC Group
LOG.trace("procesing elan remote bc group for tunnel event {}", elanInfo);
try {
- elanL2GatewayMulticastUtils.setupElanBroadcastGroups(elanInfo, srcDpId);
+ txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+ confTx -> elanL2GatewayMulticastUtils.setupElanBroadcastGroups(elanInfo, srcDpId,
+ confTx)).get();
} catch (RuntimeException e) {
LOG.error("Error while adding remote bc group for {} on dpId {} ", elanName, srcDpId);
}
* @param intrf
* the interface
*/
- public void handleExternalTunnelStateEvent(ExternalTunnel externalTunnel, Interface intrf) {
+ void handleExternalTunnelStateEvent(ExternalTunnel externalTunnel, Interface intrf) {
if (!validateExternalTunnelStateEvent(externalTunnel, intrf)) {
return;
}
}
LOG.debug("Elan instance:{} is present in Dpn:{} ", elanName, dpId);
- elanL2GatewayMulticastUtils.setupElanBroadcastGroups(elanInfo, dpId);
+ final BigInteger finalDpId = dpId;
+ ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+ confTx -> elanL2GatewayMulticastUtils.setupElanBroadcastGroups(elanInfo, finalDpId, confTx)), LOG,
+ "Error setting up ELAN BGs");
// install L2gwDevices local macs in dpn.
elanL2GatewayUtils.installL2gwDeviceMacsInDpn(dpId, externalNodeId, elanInfo, intrf.getName());
// Install dpn macs on external device
public void handleExternalInterfaceEvent(ElanInstance elanInstance, DpnInterfaces dpnInterfaces,
BigInteger dpId) {
LOG.debug("setting up remote BC group for elan {}", elanInstance.getPhysicalNetworkName());
- elanL2GatewayMulticastUtils.setupStandardElanBroadcastGroups(elanInstance, dpnInterfaces, dpId);
+ ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+ confTx -> elanL2GatewayMulticastUtils.setupStandardElanBroadcastGroups(elanInstance, dpnInterfaces, dpId,
+ confTx)), LOG, "Error setting up remote BC group for ELAN {}", elanInstance.getPhysicalNetworkName());
try {
Thread.sleep(WAIT_TIME_FOR_SYNC_INSTALL);
} catch (InterruptedException e) {
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
import org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar;
+import org.opendaylight.genius.infra.Datastore;
import org.opendaylight.genius.infra.Datastore.Configuration;
import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.genius.infra.TypedReadWriteTransaction;
+import org.opendaylight.genius.infra.TypedWriteTransaction;
import org.opendaylight.genius.mdsalutil.ActionInfo;
import org.opendaylight.genius.mdsalutil.BucketInfo;
import org.opendaylight.genius.mdsalutil.FlowEntity;
+import org.opendaylight.genius.mdsalutil.GroupEntity;
import org.opendaylight.genius.mdsalutil.InstructionInfo;
import org.opendaylight.genius.mdsalutil.MDSALUtil;
import org.opendaylight.genius.mdsalutil.MatchInfo;
import org.opendaylight.netvirt.elan.utils.ElanUtils;
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.idmanager.rev160406.IdManagerService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
LOG.warn("Unexpected nodeId {}", nodeId.getValue());
return;
}
- BigInteger dpId = new BigInteger(node[1]);
- createTableMissEntry(dpId);
- createMulticastFlows(dpId);
- createArpDefaultFlowsForArpCheckTable(dpId);
+ ListenableFutures.addErrorLogging(
+ txRunner.callWithNewWriteOnlyTransactionAndSubmit(Datastore.CONFIGURATION, tx -> {
+ BigInteger dpId = new BigInteger(node[1]);
+ createTableMissEntry(tx, dpId);
+ createMulticastFlows(tx, dpId);
+ createArpDefaultFlowsForArpCheckTable(dpId);
+ }), LOG, "Error handling ELAN node addition for {}", add);
}
private void createArpDefaultFlowsForArpCheckTable(BigInteger dpId) {
})));
}
- public void createTableMissEntry(BigInteger dpnId) {
- setupTableMissSmacFlow(dpnId);
- setupTableMissDmacFlow(dpnId);
- setupTableMissArpCheckFlow(dpnId);
- setupTableMissApResponderFlow(dpnId);
- setupExternalL2vniTableMissFlow(dpnId);
+ public void createTableMissEntry(TypedWriteTransaction<Configuration> tx, BigInteger dpnId) {
+ setupTableMissSmacFlow(tx, dpnId);
+ setupTableMissDmacFlow(tx, dpnId);
+ setupTableMissArpCheckFlow(tx, dpnId);
+ setupTableMissApResponderFlow(tx, dpnId);
+ setupExternalL2vniTableMissFlow(tx, dpnId);
}
- private void createMulticastFlows(BigInteger dpId) {
- createL2ControlProtocolDropFlows(dpId);
- createMulticastPuntFlows(dpId);
+ private void createMulticastFlows(TypedWriteTransaction<Configuration> tx, BigInteger dpId) {
+ createL2ControlProtocolDropFlows(tx, dpId);
+ createMulticastPuntFlows(tx, dpId);
}
- private void createMulticastPuntFlows(BigInteger dpId) {
+ private void createMulticastPuntFlows(TypedWriteTransaction<Configuration> tx, BigInteger dpId) {
if (puntLldpToController) {
- createLldpFlows(dpId);
+ createLldpFlows(tx, dpId);
}
}
- private void createLldpFlows(BigInteger dpId) {
- createLldpFlow(dpId, ElanConstants.LLDP_DST_1, "LLDP dMac Table Flow 1");
- createLldpFlow(dpId, ElanConstants.LLDP_DST_2, "LLDP dMac Table Flow 2");
- createLldpFlow(dpId, ElanConstants.LLDP_DST_3, "LLDP dMac Table Flow 3");
+ private void createLldpFlows(TypedWriteTransaction<Configuration> tx, BigInteger dpId) {
+ createLldpFlow(tx, dpId, ElanConstants.LLDP_DST_1, "LLDP dMac Table Flow 1");
+ createLldpFlow(tx, dpId, ElanConstants.LLDP_DST_2, "LLDP dMac Table Flow 2");
+ createLldpFlow(tx, dpId, ElanConstants.LLDP_DST_3, "LLDP dMac Table Flow 3");
}
- private void createLldpFlow(BigInteger dpId, String dstMac, String flowName) {
+ private void createLldpFlow(TypedWriteTransaction<Configuration> tx, BigInteger dpId, String dstMac,
+ String flowName) {
List<MatchInfo> mkMatches = new ArrayList<>();
mkMatches.add(new MatchEthernetType(ElanConstants.LLDP_ETH_TYPE));
mkMatches.add(new MatchEthernetDestination(new MacAddress(dstMac)));
FlowEntity lldpFlow = MDSALUtil.buildFlowEntity(dpId, NwConstants.ELAN_DMAC_TABLE, flowId, 16, flowName, 0, 0,
ElanConstants.COOKIE_ELAN_KNOWN_DMAC, mkMatches, mkInstructions);
- mdsalManager.installFlow(lldpFlow);
+ mdsalManager.addFlow(tx, lldpFlow);
}
- private void setupTableMissSmacFlow(BigInteger dpId) {
+ private void setupTableMissSmacFlow(TypedWriteTransaction<Configuration> tx, BigInteger dpId) {
List<ActionInfo> actionsInfos = new ArrayList<>();
actionsInfos.add(new ActionPuntToController());
actionsInfos.add(new ActionLearn(0, tempSmacLearnTimeout, 0, ElanConstants.COOKIE_ELAN_LEARNED_SMAC, 0,
FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.ELAN_SMAC_TABLE,
getTableMissFlowRef(NwConstants.ELAN_SMAC_TABLE), 0, "ELAN sMac Table Miss Flow", 0, 0,
ElanConstants.COOKIE_ELAN_KNOWN_SMAC, mkMatches, mkInstructions);
- mdsalManager.installFlow(flowEntity);
+ mdsalManager.addFlow(tx, flowEntity);
- addSmacBaseTableFlow(dpId);
- addSmacLearnedTableFlow(dpId);
+ addSmacBaseTableFlow(tx, dpId);
+ addSmacLearnedTableFlow(tx, dpId);
}
- private void addSmacBaseTableFlow(BigInteger dpId) {
+ private void addSmacBaseTableFlow(TypedWriteTransaction<Configuration> tx, BigInteger dpId) {
// T48 - resubmit to T49 & T50
List<ActionInfo> actionsInfo = new ArrayList<>();
actionsInfo.add(new ActionNxResubmit(NwConstants.ELAN_SMAC_LEARNED_TABLE));
FlowEntity doubleResubmitTable = MDSALUtil.buildFlowEntity(dpId, NwConstants.ELAN_BASE_TABLE,
getTableMissFlowRef(NwConstants.ELAN_BASE_TABLE), 0, "Elan sMac resubmit table", 0, 0,
ElanConstants.COOKIE_ELAN_BASE_SMAC, mkMatch, mkInstruct);
- mdsalManager.installFlow(doubleResubmitTable);
+ mdsalManager.addFlow(tx, doubleResubmitTable);
}
- private void addSmacLearnedTableFlow(BigInteger dpId) {
+ private void addSmacLearnedTableFlow(TypedWriteTransaction<Configuration> tx, BigInteger dpId) {
// T50 - match on Reg4 and goto T51
List<MatchInfoBase> mkMatches = new ArrayList<>();
mkMatches.add(new NxMatchRegister(NxmNxReg4.class, LEARN_MATCH_REG4_VALUE));
MDSALUtil.buildFlowEntity(dpId, NwConstants.ELAN_SMAC_TABLE, flowRef, 10, "ELAN sMac Table Reg4 Flow",
0, 0, ElanConstants.COOKIE_ELAN_KNOWN_SMAC.add(BigInteger.valueOf(LEARN_MATCH_REG4_VALUE)),
mkMatches, mkInstructions);
- mdsalManager.installFlow(flowEntity);
+ mdsalManager.addFlow(tx, flowEntity);
}
- private void setupTableMissDmacFlow(BigInteger dpId) {
+ private void setupTableMissDmacFlow(TypedWriteTransaction<Configuration> tx, BigInteger dpId) {
List<MatchInfo> mkMatches = new ArrayList<>();
List<InstructionInfo> mkInstructions = new ArrayList<>();
getTableMissFlowRef(NwConstants.ELAN_DMAC_TABLE), 0, "ELAN dMac Table Miss Flow", 0, 0,
ElanConstants.COOKIE_ELAN_KNOWN_DMAC, mkMatches, mkInstructions);
- mdsalManager.installFlow(flowEntity);
+ mdsalManager.addFlow(tx, flowEntity);
}
- private void setupExternalL2vniTableMissFlow(BigInteger dpnId) {
+ private void setupExternalL2vniTableMissFlow(TypedWriteTransaction<Configuration> tx, BigInteger dpnId) {
List<MatchInfo> matches = new ArrayList<>();
List<ActionInfo> actionsInfos = Collections.singletonList(new ActionNxResubmit(NwConstants
.LPORT_DISPATCHER_TABLE));
getTableMissFlowRef(NwConstants.L2VNI_EXTERNAL_TUNNEL_DEMUX_TABLE), 0,
"External L2VNI Table Miss Flow", 0, 0,
ElanConstants.COOKIE_L2VNI_DEMUX, matches, instructions);
- mdsalManager.installFlow(flowEntity);
+ mdsalManager.addFlow(tx, flowEntity);
}
- private void createL2ControlProtocolDropFlows(BigInteger dpId) {
+ private void createL2ControlProtocolDropFlows(TypedWriteTransaction<Configuration> tx, BigInteger dpId) {
List<MatchInfo> mkMatches = new ArrayList<>();
MatchEthernetDestination matchEthDst =
new MatchEthernetDestination(new MacAddress(ElanConstants.L2_CONTROL_PACKETS_DMAC),
"L2 control packets dMac Table Flow", 0, 0, ElanConstants.COOKIE_ELAN_KNOWN_DMAC, mkMatches,
mkInstructions);
- mdsalManager.installFlow(flow);
+ mdsalManager.addFlow(tx, flow);
}
private String getTableMissFlowRef(long tableId) {
- return new StringBuffer().append(tableId).toString();
+ return String.valueOf(tableId);
}
@Override
return ElanNodeListener.this;
}
- private void setupTableMissApResponderFlow(final BigInteger dpnId) {
- mdsalManager.installFlow(dpnId, ArpResponderUtil.getArpResponderTableMissFlow(dpnId));
+ private void setupTableMissApResponderFlow(TypedWriteTransaction<Configuration> tx, final BigInteger dpnId) {
+ mdsalManager.addFlow(tx, ArpResponderUtil.getArpResponderTableMissFlow(dpnId));
}
- private void setupTableMissArpCheckFlow(BigInteger dpnId) {
- mdsalManager.installFlow(dpnId,
+ private void setupTableMissArpCheckFlow(TypedWriteTransaction<Configuration> tx, BigInteger dpnId) {
+ mdsalManager.addFlow(tx,
MDSALUtil.buildFlowEntity(dpnId, NwConstants.ARP_CHECK_TABLE,
String.valueOf("L2.ELAN." + NwConstants.ARP_CHECK_TABLE), NwConstants.TABLE_MISS_PRIORITY,
ArpResponderConstant.DROP_FLOW_NAME.value(), 0, 0, NwConstants.COOKIE_ARP_RESPONDER,
throws ExecutionException, InterruptedException {
long arpRequestGroupId = ArpResponderUtil.retrieveStandardArpResponderGroupId(idManagerService);
List<BucketInfo> buckets = ArpResponderUtil.getDefaultBucketInfos(NwConstants.ARP_RESPONDER_TABLE);
- ArpResponderUtil.installGroup(mdsalManager, dpId, arpRequestGroupId,
- ArpResponderConstant.GROUP_FLOW_NAME.value(), buckets);
+ LOG.trace("Installing group flow on dpn {}", dpId);
+ GroupEntity groupEntity =
+ MDSALUtil.buildGroupEntity(dpId, arpRequestGroupId, ArpResponderConstant.GROUP_FLOW_NAME.value(),
+ GroupTypes.GroupAll, buckets);
+ mdsalManager.addGroup(tx, groupEntity);
InstanceIdentifier<Group> groupIid = ElanUtils.getGroupInstanceid(dpId, arpRequestGroupId);
if (tx.read(groupIid).get().isPresent()) {
LOG.info("group {} is present in the config hence adding the flow", arpRequestGroupId);
import javax.inject.Singleton;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.infra.Datastore;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.genius.interfacemanager.exceptions.InterfaceAlreadyExistsException;
import org.opendaylight.genius.interfacemanager.globals.IfmConstants;
import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
import org.opendaylight.genius.utils.ServiceIndex;
import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundConstants;
import org.opendaylight.infrautils.inject.AbstractLifecycle;
+import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
import org.opendaylight.mdsal.eos.binding.api.Entity;
import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipCandidateRegistration;
import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipService;
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.PhysAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolOutput;
private final IInterfaceManager interfaceManager;
private final ElanBridgeManager bridgeMgr;
private final DataBroker broker;
+ private final ManagedNewTransactionRunner txRunner;
private final ElanUtils elanUtils;
private final SouthboundUtils southboundUtils;
private final IMdsalApiManager mdsalManager;
this.interfaceManager = interfaceManager;
this.bridgeMgr = bridgeMgr;
this.broker = dataBroker;
+ this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
this.elanUtils = elanUtils;
this.southboundUtils = southboundUtils;
this.elanInstanceCache = elanInstanceCache;
return;
}
String flowId = ArpResponderUtil.getFlowId(lportTag, ipAddress);
- ArpResponderUtil.installFlow(mdsalManager, dpnId, flowId, flowId, NwConstants.DEFAULT_ARP_FLOW_PRIORITY,
+ Flow flowEntity =
+ MDSALUtil.buildFlowNew(NwConstants.ARP_RESPONDER_TABLE, flowId, NwConstants.DEFAULT_ARP_FLOW_PRIORITY,
+ flowId, 0, 0,
ArpResponderUtil.generateCookie(lportTag, ipAddress),
ArpResponderUtil.getMatchCriteria(lportTag, elanInstance, ipAddress),
arpResponderInput.getInstructions());
+ ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(Datastore.CONFIGURATION,
+ tx -> mdsalManager.addFlow(tx, dpnId, flowEntity)), LOG, "Error adding flow {}", flowEntity);
LOG.info("Installed the ARP Responder flow for Interface {}", ingressInterfaceName);
}
int lportTag = arpResponderInput.getLportTag();
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), arpResponderInput.getInstructions());
+ Flow flowEntity =
+ MDSALUtil.buildFlowNew(NwConstants.ARP_RESPONDER_TABLE, flowId, NwConstants.DEFAULT_ARP_FLOW_PRIORITY,
+ flowId, 0, 0,
+ ArpResponderUtil.generateCookie(lportTag, ipAddress),
+ ArpResponderUtil.getMatchCriteria(lportTag, elanInstance, ipAddress),
+ arpResponderInput.getInstructions());
+ ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(Datastore.CONFIGURATION,
+ tx -> mdsalManager.addFlow(tx, dpnId, flowEntity)), LOG, "Error adding flow {}", flowEntity);
LOG.trace("Installed the ExternalTunnel ARP Responder flow for ElanInstance {}", elanInstanceName);
}
*/
package org.opendaylight.netvirt.elan.l2gw.listeners;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+
import java.math.BigInteger;
import java.util.List;
import java.util.concurrent.ConcurrentMap;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.genius.datastoreutils.AsyncClusteredDataTreeChangeListenerBase;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
import org.opendaylight.netvirt.elan.cache.ElanInstanceCache;
import org.opendaylight.netvirt.elan.l2gw.utils.ElanL2GatewayMulticastUtils;
import org.opendaylight.netvirt.elan.utils.ElanClusterUtils;
private static final Logger LOG = LoggerFactory.getLogger(ElanGroupListener.class);
private final DataBroker broker;
+ private final ManagedNewTransactionRunner txRunner;
private final ElanClusterUtils elanClusterUtils;
private final ElanUtils elanUtils;
private final ElanL2GatewayMulticastUtils elanL2GatewayMulticastUtils;
ElanL2GatewayMulticastUtils elanL2GatewayMulticastUtils, ElanInstanceCache elanInstanceCache) {
super(Group.class, ElanGroupListener.class);
broker = db;
+ this.txRunner = new ManagedNewTransactionRunnerImpl(db);
this.elanClusterUtils = elanClusterUtils;
this.elanUtils = elanUtils;
this.elanL2GatewayMulticastUtils = elanL2GatewayMulticastUtils;
LOG.trace("no of buckets mismatched {} {}", elanInstance.getElanInstanceName(),
update.key().getGroupId());
elanClusterUtils.runOnlyInOwnerNode(elanInstance.getElanInstanceName(), "updating broadcast group", () -> {
- elanL2GatewayMulticastUtils.setupElanBroadcastGroups(elanInstance, dpnId);
+ ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+ confTx -> elanL2GatewayMulticastUtils.setupElanBroadcastGroups(elanInstance, dpnId, confTx)),
+ LOG, "Error setting up ELAN BGs");
return null;
});
} else {
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
+import org.opendaylight.genius.infra.Datastore;
import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.infra.TypedWriteTransaction;
import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
import org.opendaylight.genius.mdsalutil.MDSALUtil;
import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
}
}
- public void updateRemoteBroadcastGroupForAllElanDpns(ElanInstance elanInfo) {
+ public void updateRemoteBroadcastGroupForAllElanDpns(ElanInstance elanInfo,
+ TypedWriteTransaction<Datastore.Configuration> confTx) {
List<DpnInterfaces> dpns = elanUtils.getInvolvedDpnsInElan(elanInfo.getElanInstanceName());
for (DpnInterfaces dpn : dpns) {
- setupElanBroadcastGroups(elanInfo, dpn.getDpId());
+ setupElanBroadcastGroups(elanInfo, dpn.getDpId(), confTx);
}
}
- public void setupElanBroadcastGroups(ElanInstance elanInfo, BigInteger dpnId) {
- setupElanBroadcastGroups(elanInfo, null, dpnId);
+ public void setupElanBroadcastGroups(ElanInstance elanInfo, BigInteger dpnId,
+ TypedWriteTransaction<Datastore.Configuration> confTx) {
+ setupElanBroadcastGroups(elanInfo, null, dpnId, confTx);
}
- public void setupElanBroadcastGroups(ElanInstance elanInfo, DpnInterfaces dpnInterfaces, BigInteger dpnId) {
- setupStandardElanBroadcastGroups(elanInfo, dpnInterfaces, dpnId);
- setupLeavesEtreeBroadcastGroups(elanInfo, dpnInterfaces, dpnId);
+ public void setupElanBroadcastGroups(ElanInstance elanInfo, DpnInterfaces dpnInterfaces, BigInteger dpnId,
+ TypedWriteTransaction<Datastore.Configuration> confTx) {
+ setupStandardElanBroadcastGroups(elanInfo, dpnInterfaces, dpnId, confTx);
+ setupLeavesEtreeBroadcastGroups(elanInfo, dpnInterfaces, dpnId, confTx);
}
- public void setupStandardElanBroadcastGroups(ElanInstance elanInfo, DpnInterfaces dpnInterfaces, BigInteger dpnId) {
+ public void setupStandardElanBroadcastGroups(ElanInstance elanInfo, DpnInterfaces dpnInterfaces, BigInteger dpnId,
+ TypedWriteTransaction<Datastore.Configuration> confTx) {
List<Bucket> listBucket = new ArrayList<>();
int bucketId = 0;
int actionKey = 0;
Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll,
MDSALUtil.buildBucketLists(listBucket));
LOG.trace("Installing the remote BroadCast Group:{}", group);
- mdsalManager.syncInstallGroup(dpnId, group);
+ mdsalManager.addGroup(confTx, dpnId, group);
}
- public void setupLeavesEtreeBroadcastGroups(ElanInstance elanInfo, DpnInterfaces dpnInterfaces, BigInteger dpnId) {
+ public void setupLeavesEtreeBroadcastGroups(ElanInstance elanInfo, DpnInterfaces dpnInterfaces, BigInteger dpnId,
+ TypedWriteTransaction<Datastore.Configuration> confTx) {
EtreeInstance etreeInstance = elanInfo.augmentation(EtreeInstance.class);
if (etreeInstance != null) {
long etreeLeafTag = etreeInstance.getEtreeLeafTagVal().getValue();
Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll,
MDSALUtil.buildBucketLists(listBucket));
LOG.trace("Installing the remote BroadCast Group:{}", group);
- mdsalManager.syncInstallGroup(dpnId, group);
+ mdsalManager.addGroup(confTx, dpnId, group);
}
}
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.Datastore;
import org.opendaylight.genius.infra.Datastore.Configuration;
import org.opendaylight.genius.infra.Datastore.Operational;
import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
}
public void removeDmacRedirectToDispatcherFlows(Long elanTag, String macAddress, List<BigInteger> dpnIds) {
- for (BigInteger dpId : dpnIds) {
- String flowId = getKnownDynamicmacFlowRef(NwConstants.ELAN_DMAC_TABLE, dpId, macAddress, elanTag);
- mdsalManager.removeFlow(dpId, MDSALUtil.buildFlow(NwConstants.ELAN_DMAC_TABLE, flowId));
- }
+ ListenableFutures.addErrorLogging(
+ txRunner.callWithNewReadWriteTransactionAndSubmit(Datastore.CONFIGURATION, tx -> {
+ for (BigInteger dpId : dpnIds) {
+ String flowId = getKnownDynamicmacFlowRef(NwConstants.ELAN_DMAC_TABLE, dpId, macAddress, elanTag);
+ mdsalManager.removeFlow(tx, dpId, MDSALUtil.buildFlow(NwConstants.ELAN_DMAC_TABLE, flowId));
+ }
+ }), LOG, "Error removing DMAC redirect to dispatcher flows");
}
public static FlowEntity buildDmacRedirectToDispatcherFlow(BigInteger dpId, String dstMacAddress,
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));
+ ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(Datastore.CONFIGURATION,
+ tx -> mdsalManager.removeFlow(tx, dpnId, ArpResponderUtil.getFlowId(lportTag, ipAddress),
+ NwConstants.ARP_RESPONDER_TABLE)), LOG, "Error removing ARP responder flow");
}
public static String getRouterPordIdFromElanInstance(DataBroker dataBroker, String elanInstanceName) {
package org.opendaylight.netvirt.elanmanager.tests;
import static org.mockito.Mockito.CALLS_REAL_METHODS;
+import static org.mockito.Mockito.mock;
import com.google.common.base.Optional;
import org.mockito.Mockito;
@Override
protected void configureBindings() {
DataBroker dataBroker = DataBrokerTestModule.dataBroker();
- EntityOwnershipService mockedEntityOwnershipService = Mockito.mock(EntityOwnershipService.class);
+ EntityOwnershipService mockedEntityOwnershipService = mock(EntityOwnershipService.class);
EntityOwnershipState mockedEntityOwnershipState = EntityOwnershipState.IS_OWNER;
Mockito.when(mockedEntityOwnershipService.getOwnershipState(Mockito.any()))
.thenReturn(Optional.of(mockedEntityOwnershipState));
bind(EntityOwnershipService.class).toInstance(mockedEntityOwnershipService);
bind(L2GatewayCache.class).to(L2GatewayCacheImpl.class);
bind(HwvtepNodeHACache.class).to(HwvtepNodeHACacheImpl.class);
- bind(ServiceRecoveryRegistry.class).toInstance(Mockito.mock(ServiceRecoveryRegistry.class));
- bind(INeutronVpnManager.class).toInstance(Mockito.mock(NeutronvpnManagerImpl.class));
- IVpnManager ivpnManager = Mockito.mock(VpnManagerTestImpl.class, CALLS_REAL_METHODS);
- bind(IMdsalApiManager.class).toInstance(new MDSALManager(dataBroker,
- Mockito.mock(PacketProcessingService.class)));
+ bind(ServiceRecoveryRegistry.class).toInstance(mock(ServiceRecoveryRegistry.class));
+ bind(INeutronVpnManager.class).toInstance(mock(NeutronvpnManagerImpl.class));
+ IVpnManager ivpnManager = mock(VpnManagerTestImpl.class, CALLS_REAL_METHODS);
+ MDSALManager mockedMdsalManager = new MDSALManager(dataBroker, mock(PacketProcessingService.class));
+ bind(IMdsalApiManager.class).toInstance(mockedMdsalManager);
// Bindings for external services to "real" implementations
bind(LockManagerService.class).to(LockManagerServiceImpl.class);
bind(DataBroker.class).toInstance(dataBroker);
bind(DataBroker.class).annotatedWith(OsgiService.class).toInstance(dataBroker);
- bind(IdManagerService.class).toInstance(Mockito.mock(IdHelper.class, CALLS_REAL_METHODS));
+ bind(IdManagerService.class).toInstance(mock(IdHelper.class, CALLS_REAL_METHODS));
bind(IInterfaceManager.class).toInstance(testInterfaceManager);
bind(TestInterfaceManager.class).toInstance(testInterfaceManager);
bind(IITMProvider.class).toInstance(testItmProvider);
InterfaceMetaUtils interfaceMetaUtils = new InterfaceMetaUtils(dataBroker,
- Mockito.mock(IdHelper.class, CALLS_REAL_METHODS),
- Mockito.mock(BatchingUtils.class));
+ mock(IdHelper.class, CALLS_REAL_METHODS),
+ mock(BatchingUtils.class));
InterfaceManagerCommonUtils interfaceManagerCommonUtils = new InterfaceManagerCommonUtils(
dataBroker,
- new MDSALManager(dataBroker, Mockito.mock(PacketProcessingService.class)),
- Mockito.mock(IdHelper.class, CALLS_REAL_METHODS),
+ mockedMdsalManager,
+ mock(IdHelper.class, CALLS_REAL_METHODS),
interfaceMetaUtils,
- Mockito.mock(BatchingUtils.class));
+ mock(BatchingUtils.class));
bind(OdlInterfaceRpcService.class).toInstance(ElanEgressActionsHelper.newInstance(interfaceManagerCommonUtils,
bind(ItmRpcService.class).toInstance(itmRpcService);
bind(ItmRpcTestImpl.class).toInstance((ItmRpcTestImpl)itmRpcService);
bind(DataImportBootReady.class).annotatedWith(OsgiService.class).toInstance(new DataImportBootReady() {});
- bind(DiagStatusService.class).toInstance(Mockito.mock(DiagStatusService.class));
+ bind(DiagStatusService.class).toInstance(mock(DiagStatusService.class));
bind(IVpnManager.class).toInstance(ivpnManager);
bind(IBgpManager.class).toInstance(ibgpManager);
bind(DataImportBootReady.class).toInstance(new DataImportBootReady() {});