use of org.opendaylight.mdsal.binding.util.Datastore.OPERATIONAL in project netvirt by opendaylight.
the class L3vpnPopulator method addToLabelMapper.
public void addToLabelMapper(Uint32 label, Uint64 dpnId, String prefix, List<String> nextHopIpList, Uint32 vpnId, @Nullable String vpnInterfaceName, @Nullable Uint32 elanTag, boolean isSubnetRoute, String rd) {
final String labelStr = requireNonNull(label, "addToLabelMapper: label cannot be null or empty!").toString();
requireNonNull(prefix, "addToLabelMapper: prefix cannot be null or empty!");
requireNonNull(vpnId, "addToLabelMapper: vpnId cannot be null or empty!");
requireNonNull(rd, "addToLabelMapper: rd cannot be null or empty!");
if (!isSubnetRoute) {
// NextHop must be present for non-subnetroute entries
requireNonNull(nextHopIpList, "addToLabelMapper: nextHopIp cannot be null or empty!");
}
// FIXME: separate this out somehow?
final ReentrantLock lock = JvmGlobalLocks.getLockForString(labelStr);
lock.lock();
try {
addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, tx -> {
LOG.info("addToLabelMapper: label {} dpn {} prefix {} nexthoplist {} vpnid {} vpnIntfcName {} rd {}" + " elanTag {}", labelStr, dpnId, prefix, nextHopIpList, vpnId, vpnInterfaceName, rd, elanTag);
if (dpnId != null) {
LabelRouteInfoBuilder lriBuilder = new LabelRouteInfoBuilder();
lriBuilder.setLabel(label).setDpnId(dpnId).setPrefix(prefix).setNextHopIpList(nextHopIpList).setParentVpnid(vpnId).setIsSubnetRoute(isSubnetRoute);
if (elanTag != null) {
lriBuilder.setElanTag(elanTag);
} else {
LOG.warn("addToLabelMapper: elanTag is null for label {} prefix {} rd {} vpnId {}", labelStr, prefix, rd, vpnId);
}
if (vpnInterfaceName != null) {
lriBuilder.setVpnInterfaceName(vpnInterfaceName);
} else {
LOG.warn("addToLabelMapper: vpn interface is null for label {} prefix {} rd {} vpnId {}", labelStr, prefix, rd, vpnId);
}
lriBuilder.setParentVpnRd(rd);
VpnInstanceOpDataEntry vpnInstanceOpDataEntry = vpnUtil.getVpnInstanceOpData(rd);
if (vpnInstanceOpDataEntry != null) {
List<String> vpnInstanceNames = Collections.singletonList(vpnInstanceOpDataEntry.getVpnInstanceName());
lriBuilder.setVpnInstanceList(vpnInstanceNames);
}
LabelRouteInfo lri = lriBuilder.build();
InstanceIdentifier<LabelRouteInfo> lriIid = InstanceIdentifier.builder(LabelRouteMap.class).child(LabelRouteInfo.class, new LabelRouteInfoKey(label)).build();
tx.mergeParentStructureMerge(lriIid, lri);
LOG.info("addToLabelMapper: Added label route info to label {} prefix {} nextHopList {} vpnId {}" + " interface {} rd {} elantag {}", labelStr, prefix, nextHopIpList, vpnId, vpnInterfaceName, rd, elanTag);
} else {
LOG.warn("addToLabelMapper: Can't add entry to label map for label {} prefix {} nextHopList {}" + " vpnId {} interface {} rd {} elantag {}, dpnId is null", labelStr, prefix, nextHopIpList, vpnId, vpnInterfaceName, rd, elanTag);
}
}), LOG, "addToLabelMapper");
} finally {
lock.unlock();
}
}
use of org.opendaylight.mdsal.binding.util.Datastore.OPERATIONAL in project netvirt by opendaylight.
the class ElanInterfaceManager method setupEntriesForElanInterface.
@SuppressWarnings("checkstyle:ForbidCertainMethod")
List<ListenableFuture<?>> setupEntriesForElanInterface(ElanInstance elanInstance, ElanInterface elanInterface, InterfaceInfo interfaceInfo, boolean isFirstInterfaceInDpn) {
String elanInstanceName = elanInstance.getElanInstanceName();
String interfaceName = elanInterface.getName();
List<ListenableFuture<?>> futures = new ArrayList<>();
Uint64 dpId = interfaceInfo.getDpId();
boolean isInterfaceOperational = isOperational(interfaceInfo);
futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, confTx -> {
futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, operTx -> {
installEntriesForElanInterface(elanInstance, elanInterface, interfaceInfo, isFirstInterfaceInDpn, confTx);
Map<StaticMacEntriesKey, StaticMacEntries> staticMacEntriesMap = elanInterface.nonnullStaticMacEntries();
List<PhysAddress> staticMacAddresses = new ArrayList<>();
if (ElanUtils.isNotEmpty(staticMacEntriesMap.values())) {
for (StaticMacEntries staticMacEntry : staticMacEntriesMap.values()) {
InstanceIdentifier<MacEntry> macId = getMacEntryOperationalDataPath(elanInstanceName, staticMacEntry.getMacAddress());
Optional<MacEntry> existingMacEntry = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, macId);
if (existingMacEntry.isPresent()) {
elanForwardingEntriesHandler.updateElanInterfaceForwardingTablesList(elanInstanceName, interfaceName, existingMacEntry.get().getInterface(), existingMacEntry.get(), operTx);
} else {
elanForwardingEntriesHandler.addElanInterfaceForwardingTableList(elanInstanceName, interfaceName, staticMacEntry, operTx);
}
if (isInterfaceOperational) {
// Setting SMAC, DMAC, UDMAC in this DPN and also in other
// DPNs
String macAddress = staticMacEntry.getMacAddress().getValue();
LOG.info("programming smac and dmacs for {} on source and other DPNs for elan {} and interface" + " {}", macAddress, elanInstanceName, interfaceName);
EVENT_LOGGER.debug("ELAN-MacFlows, ADD {} Instance {} Mac {}", interfaceName, elanInstanceName, macAddress);
elanUtils.setupMacFlows(elanInstance, interfaceInfo, ElanConstants.STATIC_MAC_TIMEOUT, staticMacEntry.getMacAddress().getValue(), true, confTx);
}
}
if (isInterfaceOperational) {
// on purpose.
for (StaticMacEntries staticMacEntry : staticMacEntriesMap.values()) {
staticMacAddresses.add(staticMacEntry.getMacAddress());
}
elanL2GatewayUtils.scheduleAddDpnMacInExtDevices(elanInstance.getElanInstanceName(), dpId, staticMacAddresses);
}
}
}));
}));
futures.forEach(ElanUtils::waitForTransactionToComplete);
if (isInterfaceOperational && !interfaceManager.isExternalInterface(interfaceName)) {
// At this point, the interface is operational and D/SMAC flows have been configured, mark the port active
try {
Port neutronPort = neutronVpnManager.getNeutronPort(interfaceName);
if (neutronPort != null) {
NeutronUtils.updatePortStatus(interfaceName, NeutronUtils.PORT_STATUS_ACTIVE, broker);
}
} catch (IllegalArgumentException ex) {
LOG.trace("Interface: {} is not part of Neutron Network", interfaceName);
}
}
return futures;
}
use of org.opendaylight.mdsal.binding.util.Datastore.OPERATIONAL in project netvirt by opendaylight.
the class DhcpNeutronPortListener method update.
@Override
public void update(InstanceIdentifier<Port> identifier, Port original, Port update) {
if (!config.isControllerDhcpEnabled()) {
return;
}
LOG.trace("Port changed to {}", update);
// With Ipv6 changes we can get ipv4 subnets later. The below check is to support such scenario.
if (original.nonnullFixedIps().size() < update.nonnullFixedIps().size()) {
final String interfaceName = update.getUuid().getValue();
List<FixedIps> updatedFixedIps = new ArrayList<>(update.nonnullFixedIps().values());
// Need to check only the newly added fixed ip.
updatedFixedIps.removeAll(original.nonnullFixedIps().values());
Subnet subnet = dhcpManager.getNeutronSubnet(updatedFixedIps);
if (null == subnet || !subnet.isEnableDhcp()) {
LOG.trace("Subnet is null/not ipv4 or not enabled {}", subnet);
return;
}
// Binding the DHCP service for an existing port because of subnet change.
jobCoordinator.enqueueJob(DhcpServiceUtils.getJobKey(interfaceName), () -> Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
LOG.debug("Binding DHCP service for interface {}", interfaceName);
DhcpServiceUtils.bindDhcpService(interfaceName, NwConstants.DHCP_TABLE, tx);
})), DhcpMConstants.RETRY_COUNT);
jobCoordinator.enqueueJob(DhcpServiceUtils.getJobKey(interfaceName), () -> {
Uint64 dpnId = interfaceManager.getDpnForInterface(interfaceName);
if (dpnId == null || dpnId.equals(DhcpMConstants.INVALID_DPID)) {
LOG.trace("Unable to install the DHCP flow since dpn is not available");
return Collections.emptyList();
}
String vmMacAddress = txRunner.applyWithNewReadWriteTransactionAndSubmit(OPERATIONAL, tx -> DhcpServiceUtils.getAndUpdateVmMacAddress(tx, interfaceName, dhcpManager)).get();
return Collections.singletonList(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> dhcpManager.installDhcpEntries(dpnId, vmMacAddress, tx)));
}, DhcpMConstants.RETRY_COUNT);
}
if (!isVnicTypeDirectOrMacVtap(update)) {
LOG.trace("Port updated is normal {}", update.getUuid());
if (isVnicTypeDirectOrMacVtap(original)) {
LOG.trace("Original Port was direct/macvtap {} so removing flows and cache entry if any", update.getUuid());
removePort(original);
}
return;
}
if (!isVnicTypeDirectOrMacVtap(original)) {
LOG.trace("Original port was normal and updated is direct. Calling addPort()");
addPort(update);
return;
}
String macOriginal = getMacAddress(original);
String macUpdated = getMacAddress(update);
String segmentationIdOriginal = DhcpServiceUtils.getSegmentationId(original.getNetworkId(), broker);
String segmentationIdUpdated = DhcpServiceUtils.getSegmentationId(update.getNetworkId(), broker);
if (macOriginal != null && !macOriginal.equalsIgnoreCase(macUpdated) && segmentationIdOriginal != null && !segmentationIdOriginal.equalsIgnoreCase(segmentationIdUpdated)) {
LOG.trace("Mac/segment id has changed");
dhcpExternalTunnelManager.removeVniMacToPortCache(Uint64.valueOf(segmentationIdOriginal), macOriginal);
dhcpExternalTunnelManager.updateVniMacToPortCache(Uint64.valueOf(segmentationIdUpdated), macUpdated, update);
}
}
use of org.opendaylight.mdsal.binding.util.Datastore.OPERATIONAL in project netvirt by opendaylight.
the class ElanInstanceEntityOwnershipListener method ownershipChanged.
@SuppressWarnings("checkstyle:IllegalCatch")
@Override
public void ownershipChanged(EntityOwnershipChange ownershipChange) {
LOG.info("Entity Ownership changed for the entity: {}", ownershipChange);
if (!ownershipChange.getState().isOwner()) {
if (ft != null) {
ft.cancel(false);
ft = null;
}
return;
}
if (!ownershipChange.getState().wasOwner() && ownershipChange.getState().isOwner()) {
if (ft != null) {
ft.cancel(false);
ft = null;
}
ft = scheduler.getScheduledExecutorService().schedule(() -> {
try {
// check if i'm the owner
if (ownershipChange.getState().isOwner()) {
LOG.info("Elan Entity owner is: {}", ownershipChange);
txRunner.callWithNewReadOnlyTransactionAndClose(CONFIGURATION, tx -> {
l2GatewayConnectionListener.loadL2GwConnectionCache(tx);
});
InstanceIdentifier<ElanDpnInterfaces> elanDpnInterfacesInstanceIdentifier = InstanceIdentifier.builder(ElanDpnInterfaces.class).build();
txRunner.callWithNewReadOnlyTransactionAndClose(OPERATIONAL, tx -> {
Optional<ElanDpnInterfaces> optional = Optional.empty();
try {
optional = tx.read(elanDpnInterfacesInstanceIdentifier).get();
} catch (ExecutionException | InterruptedException e) {
LOG.error("Exception While reading ElanDpnInterfaces", e);
}
if (optional.isPresent() && optional.get().getElanDpnInterfacesList() != null) {
LOG.debug("Found elan dpn interfaces list");
optional.get().nonnullElanDpnInterfacesList().values().forEach(elanDpnInterfacesList -> {
List<DpnInterfaces> dpnInterfaces = new ArrayList<>(elanDpnInterfacesList.nonnullDpnInterfaces().values());
InstanceIdentifier<ElanDpnInterfacesList> parentIid = InstanceIdentifier.builder(ElanDpnInterfaces.class).child(ElanDpnInterfacesList.class, new ElanDpnInterfacesListKey(elanDpnInterfacesList.getElanInstanceName())).build();
for (DpnInterfaces dpnInterface : dpnInterfaces) {
LOG.debug("Found elan dpn interfaces");
elanDpnInterfaceClusteredListener.add(parentIid.child(DpnInterfaces.class, dpnInterface.key()), dpnInterface);
}
});
}
});
} else {
LOG.info("Not the owner for Elan entity {}", ownershipChange);
}
ft = null;
} catch (Exception e) {
LOG.error("Failed to read mdsal ", e);
}
}, ELAN_EOS_DELAY, TimeUnit.MINUTES);
}
}
use of org.opendaylight.mdsal.binding.util.Datastore.OPERATIONAL in project netvirt by opendaylight.
the class HAOpNodeListener method readAndCopyChildPsOpToParent.
private void readAndCopyChildPsOpToParent(Node childNode, TypedReadWriteTransaction<Operational> tx) {
String childGlobalNodeId = childNode.getNodeId().getValue();
List<InstanceIdentifier> childPsIids = new ArrayList<>();
HwvtepGlobalAugmentation hwvtepGlobalAugmentation = childNode.augmentation(HwvtepGlobalAugmentation.class);
if (hwvtepGlobalAugmentation == null || HwvtepHAUtil.isEmpty(hwvtepGlobalAugmentation.nonnullSwitches().values())) {
haOpClusteredListener.getConnectedNodes().stream().filter(connectedIid -> IS_PS_CHILD_TO_GLOBAL_NODE.test(childGlobalNodeId, connectedIid)).forEach(connectedIid -> childPsIids.add(connectedIid));
} else {
hwvtepGlobalAugmentation.getSwitches().values().forEach(switches -> childPsIids.add(switches.getSwitchRef().getValue()));
}
if (childPsIids.isEmpty()) {
LOG.info("HAOpNodeListener No child ps found for global {}", childGlobalNodeId);
}
childPsIids.forEach(psIid -> {
try {
InstanceIdentifier<Node> childPsIid = psIid;
Optional<Node> childPsNode = tx.read(childPsIid).get();
if (childPsNode.isPresent()) {
LOG.debug("Child oper PS node found");
onPsNodeAdd(childPsIid, childPsNode.get(), tx);
} else {
LOG.error("HAOpNodeListener Child oper ps node not found {}", childPsIid);
}
} catch (ExecutionException | InterruptedException e) {
LOG.error("HAOpNodeListener Failed to read child ps node {}", psIid);
}
});
}
Aggregations