use of org.opendaylight.mdsal.binding.util.Datastore.Configuration 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.Configuration in project netvirt by opendaylight.
the class LocalUcastMacListener method deleteElanMacEntry.
private void deleteElanMacEntry(InstanceIdentifier<LocalUcastMacs> identifier, LocalUcastMacs macRemoved) {
String hwvtepNodeId = identifier.firstKeyOf(Node.class).getNodeId().getValue();
String macAddress = macRemoved.getMacEntryKey().getValue().toLowerCase(Locale.getDefault());
String elanName = getElanName(macRemoved);
PhysAddress phyAddress = new PhysAddress(macRemoved.getMacEntryKey().getValue());
InstanceIdentifier<MacEntry> elanMacEntryIid = ElanUtils.getMacEntryOperationalDataPath(elanName, phyAddress);
localMacEntryCache.remove(elanMacEntryIid);
elanClusterUtils.runOnlyInOwnerNode(hwvtepNodeId + ":" + macAddress + HwvtepHAUtil.L2GW_JOB_KEY, "remove elan mac entry from config", () -> {
return Lists.newArrayList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> tx.delete(elanMacEntryIid)));
});
}
use of org.opendaylight.mdsal.binding.util.Datastore.Configuration in project netvirt by opendaylight.
the class LocalUcastMacListener method updateElanMacInConfigDb.
private void updateElanMacInConfigDb(InstanceIdentifier<LocalUcastMacs> identifier, LocalUcastMacs macAdded) {
String hwvtepNodeId = identifier.firstKeyOf(Node.class).getNodeId().getValue();
String macAddress = macAdded.getMacEntryKey().getValue().toLowerCase(Locale.getDefault());
String elanName = getElanName(macAdded);
PhysAddress phyAddress = new PhysAddress(macAdded.getMacEntryKey().getValue());
MacEntry newElanMac = new MacEntryBuilder().setSrcTorNodeid(hwvtepNodeId).setMacAddress(phyAddress).build();
InstanceIdentifier<MacEntry> iid = ElanUtils.getMacEntryOperationalDataPath(elanName, phyAddress);
localMacEntryCache.put(iid, newElanMac);
elanClusterUtils.runOnlyInOwnerNode(hwvtepNodeId + ":" + macAddress + HwvtepHAUtil.L2GW_JOB_KEY, "update elan mac entry", () -> {
return Lists.newArrayList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> tx.mergeParentStructurePut(iid, newElanMac)));
});
}
use of org.opendaylight.mdsal.binding.util.Datastore.Configuration 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.Configuration in project netvirt by opendaylight.
the class ElanGroupListener method update.
@Override
public void update(InstanceIdentifier<Group> identifier, @Nullable Group original, Group update) {
LOG.trace("received group updated {}", update.key().getGroupId());
final Uint64 dpnId = getDpnId(identifier.firstKeyOf(Node.class).getId().getValue());
if (dpnId == null) {
return;
}
List<L2GatewayDevice> allDevices = ElanL2GwCacheUtils.getAllElanDevicesFromCache();
if (allDevices.isEmpty()) {
LOG.trace("no elan devices present in cache {}", update.key().getGroupId());
return;
}
int expectedElanFootprint = 0;
final ElanInstance elanInstance = getElanInstanceFromGroupId(update);
if (elanInstance == null) {
LOG.trace("no elan instance is null {}", update.key().getGroupId());
return;
}
final int devicesSize = ElanL2GwCacheUtils.getInvolvedL2GwDevices(elanInstance.getElanInstanceName()).size();
if (devicesSize == 0) {
LOG.trace("no elan devices in elan cache {} {}", elanInstance.getElanInstanceName(), update.key().getGroupId());
return;
}
boolean updateGroup = false;
List<DpnInterfaces> dpns = elanUtils.getElanDPNByName(elanInstance.getElanInstanceName());
if (dpns.size() > 0) {
expectedElanFootprint += dpns.size();
} else {
updateGroup = true;
}
expectedElanFootprint += devicesSize;
if (update.getBuckets() != null && update.getBuckets().getBucket() != null) {
if (update.getBuckets().getBucket().size() != expectedElanFootprint) {
updateGroup = true;
} else {
LOG.trace("no of buckets matched perfectly {} {}", elanInstance.getElanInstanceName(), update.key().getGroupId());
}
}
if (updateGroup) {
List<Bucket> bucketList = elanL2GatewayMulticastUtils.getRemoteBCGroupBuckets(elanInstance, null, dpnId, 0, elanInstance.getElanTag().toJava());
// remove local bcgroup bucket
expectedElanFootprint--;
if (bucketList.size() != expectedElanFootprint) {
// no point in retrying if not able to meet expected foot print
return;
}
LOG.trace("no of buckets mismatched {} {}", elanInstance.getElanInstanceName(), update.key().getGroupId());
elanClusterUtils.runOnlyInOwnerNode(elanInstance.getElanInstanceName(), "updating broadcast group", () -> {
LoggingFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, confTx -> elanL2GatewayMulticastUtils.setupElanBroadcastGroups(elanInstance, dpnId, confTx)), LOG, "Error setting up ELAN BGs");
return null;
});
} else {
LOG.trace("no buckets in the update {} {}", elanInstance.getElanInstanceName(), update.key().getGroupId());
}
}
Aggregations