use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.Update in project netvirt by opendaylight.
the class IVpnLinkServiceImpl method leakExtraRoutesToVpnEndpoint.
/*
* Checks if there are static routes in Vpn1 whose nexthop is Vpn2's endpoint.
* Those routes must be leaked to Vpn1.
*
* @param vpnLink
* @param vpn1Uuid
* @param vpn2Uuid
*/
private void leakExtraRoutesToVpnEndpoint(InterVpnLinkDataComposite vpnLink, String vpn1Uuid, String vpn2Uuid) {
String vpn1Rd = vpnUtil.getVpnRd(vpn1Uuid);
String vpn2Endpoint = vpnLink.getOtherEndpointIpAddr(vpn2Uuid);
List<VrfEntry> allVpnVrfEntries = vpnUtil.getAllVrfEntries(vpn1Rd);
for (VrfEntry vrfEntry : allVpnVrfEntries) {
vrfEntry.nonnullRoutePaths().values().stream().filter(routePath -> Objects.equals(routePath.getNexthopAddress(), vpn2Endpoint)).forEach(routePath -> {
// Vpn1 has a route pointing to Vpn2's endpoint. Forcing the leaking of the route will update
// the BGP accordingly
Uint32 label = vpnUtil.getUniqueId(VpnConstants.VPN_IDPOOL_NAME, VpnUtil.getNextHopLabelKey(vpn1Rd, vrfEntry.getDestPrefix()));
if (label.longValue() == VpnConstants.INVALID_LABEL) {
LOG.error("Unable to fetch label from Id Manager. Bailing out of leaking extra routes for " + "InterVpnLink {} rd {} prefix {}", vpnLink.getInterVpnLinkName(), vpn1Rd, vrfEntry.getDestPrefix());
} else {
leakRoute(vpnLink, vpn2Uuid, vpn1Uuid, vrfEntry.getDestPrefix(), label, RouteOrigin.value(vrfEntry.getOrigin()));
}
});
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.Update in project netvirt by opendaylight.
the class InterVpnLinkListener method add.
@Override
public void add(InstanceIdentifier<InterVpnLink> identifier, InterVpnLink add) {
String ivpnLinkName = add.getName();
LOG.debug("Reacting to IVpnLink {} creation. Vpn1=[name={} EndpointIp={}] Vpn2=[name={} endpointIP={}]", ivpnLinkName, add.getFirstEndpoint().getVpnUuid(), add.getFirstEndpoint().getIpAddress(), add.getSecondEndpoint().getVpnUuid(), add.getSecondEndpoint().getIpAddress());
// Create VpnLink state
InstanceIdentifier<InterVpnLinkState> vpnLinkStateIid = InterVpnLinkUtil.getInterVpnLinkStateIid(ivpnLinkName);
InterVpnLinkState vpnLinkState = new InterVpnLinkStateBuilder().setInterVpnLinkName(ivpnLinkName).build();
MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnLinkStateIid, vpnLinkState);
InterVpnLinkKey key = add.key();
Uuid vpn1Uuid = add.getFirstEndpoint().getVpnUuid();
String vpn1Name = vpn1Uuid.getValue();
Uuid vpn2Uuid = add.getSecondEndpoint().getVpnUuid();
String vpn2Name = vpn2Uuid.getValue();
String vpn1PrimaryRd = vpnUtil.getPrimaryRd(vpn1Name);
String vpn2PrimaryRd = vpnUtil.getPrimaryRd(vpn1Name);
if (!vpnUtil.isVpnPendingDelete(vpn1PrimaryRd) && !vpnUtil.isVpnPendingDelete(vpn2PrimaryRd)) {
if (vpnUtil.getVpnInstance(vpn1Name) == null) {
String errMsg = "InterVpnLink " + ivpnLinkName + " creation error: could not find 1st endpoint Vpn " + vpn1Name;
setInError(vpnLinkStateIid, vpnLinkState, errMsg);
return;
}
if (!checkVpnAvailability(key, vpn1Name)) {
String errMsg = "InterVpnLink " + ivpnLinkName + " creation error: Vpn " + vpn1Name + " is already associated to an inter-vpn-link ";
setInError(vpnLinkStateIid, vpnLinkState, errMsg);
return;
}
// Second VPN
if (vpnUtil.getVpnInstance(vpn2Name) == null) {
String errMsg = "InterVpnLink " + ivpnLinkName + " creation error: could not find 2nd endpoint Vpn " + vpn2Name;
setInError(vpnLinkStateIid, vpnLinkState, errMsg);
return;
}
if (!checkVpnAvailability(key, vpn2Name)) {
String errMsg = "InterVpnLink " + ivpnLinkName + " creation error: Vpn " + vpn2Name + " is already associated with an inter-vpn-link";
setInError(vpnLinkStateIid, vpnLinkState, errMsg);
return;
}
interVpnLinkCache.addInterVpnLinkToCaches(add);
// Wait for VPN Operational data ready
Uint32 vpn1Id = vpnUtil.getVpnId(vpn1Name);
if (VpnConstants.INVALID_ID.equals(vpn1Id)) {
boolean vpn1Ready = vpnOpDataSyncer.waitForVpnDataReady(VpnOpDataSyncer.VpnOpDataType.vpnInstanceToId, vpn1Name, VpnConstants.PER_VPN_INSTANCE_MAX_WAIT_TIME_IN_MILLISECONDS);
if (!vpn1Ready) {
String errMsg = "InterVpnLink " + ivpnLinkName + " creation error: Operational Data for VPN " + vpn1Name + " not ready after " + VpnConstants.PER_INTERFACE_MAX_WAIT_TIME_IN_MILLISECONDS + " milliseconds";
setInError(vpnLinkStateIid, vpnLinkState, errMsg);
return;
}
}
Uint32 vpn2Id = vpnUtil.getVpnId(vpn2Name);
if (VpnConstants.INVALID_ID.equals(vpn2Id)) {
boolean vpn1Ready = vpnOpDataSyncer.waitForVpnDataReady(VpnOpDataSyncer.VpnOpDataType.vpnInstanceToId, vpn2Name, VpnConstants.PER_VPN_INSTANCE_MAX_WAIT_TIME_IN_MILLISECONDS);
if (!vpn1Ready) {
String errMsg = "InterVpnLink " + ivpnLinkName + " creation error: Operational Data for VPN " + vpn2Name + " not ready after " + VpnConstants.PER_INTERFACE_MAX_WAIT_TIME_IN_MILLISECONDS + " milliseconds";
setInError(vpnLinkStateIid, vpnLinkState, errMsg);
return;
}
}
List<Uint64> firstDpnList = ivpnLinkLocator.selectSuitableDpns(add);
if (firstDpnList != null && !firstDpnList.isEmpty()) {
List<Uint64> secondDpnList = firstDpnList;
Long firstVpnLportTag = allocateVpnLinkLportTag(key.getName() + vpn1Name);
Long secondVpnLportTag = allocateVpnLinkLportTag(key.getName() + vpn2Name);
FirstEndpointState firstEndPointState = new FirstEndpointStateBuilder().setVpnUuid(vpn1Uuid).setDpId(firstDpnList).setLportTag(firstVpnLportTag).build();
SecondEndpointState secondEndPointState = new SecondEndpointStateBuilder().setVpnUuid(vpn2Uuid).setDpId(secondDpnList).setLportTag(secondVpnLportTag).build();
interVpnLinkUtil.updateInterVpnLinkState(ivpnLinkName, InterVpnLinkState.State.Active, firstEndPointState, secondEndPointState, interVpnLinkCache);
// Note that in the DPN of the firstEndpoint we install the lportTag of the secondEndpoint and viceversa
interVpnLinkUtil.installLPortDispatcherTableFlow(ivpnLinkName, firstDpnList, vpn2Name, secondVpnLportTag);
interVpnLinkUtil.installLPortDispatcherTableFlow(ivpnLinkName, secondDpnList, vpn1Name, firstVpnLportTag);
// Update the VPN -> DPNs Map.
// Note: when a set of DPNs is calculated for Vpn1, these DPNs are added to the VpnToDpn map of Vpn2.
// Why? because we do the handover from Vpn1 to Vpn2 in those DPNs, so in those DPNs we must know how
// to reach to Vpn2 targets. If new Vpn2 targets are added later, the Fib will be maintained in these
// DPNs even if Vpn2 is not physically present there.
interVpnLinkUtil.updateVpnFootprint(vpn2Name, vpn2PrimaryRd, firstDpnList);
interVpnLinkUtil.updateVpnFootprint(vpn1Name, vpn1PrimaryRd, secondDpnList);
// Program static routes if needed
Optional<InterVpnLinkDataComposite> interVpnLink = interVpnLinkCache.getInterVpnLinkByName(ivpnLinkName);
ivpnLinkService.handleStaticRoutes(interVpnLink.get());
// Now, if the corresponding flags are activated, there will be some routes exchange
ivpnLinkService.exchangeRoutes(interVpnLink.get());
} else {
// If there is no connection to DPNs, the InterVpnLink is created and the InterVpnLinkState is also
// created with the corresponding LPortTags but no DPN is assigned since there is no DPN operative.
Long firstVpnLportTag = allocateVpnLinkLportTag(key.getName() + vpn1Name);
Long secondVpnLportTag = allocateVpnLinkLportTag(key.getName() + vpn2Name);
FirstEndpointState firstEndPointState = new FirstEndpointStateBuilder().setVpnUuid(vpn1Uuid).setLportTag(firstVpnLportTag).setDpId(Collections.emptyList()).build();
SecondEndpointState secondEndPointState = new SecondEndpointStateBuilder().setVpnUuid(vpn2Uuid).setLportTag(secondVpnLportTag).setDpId(Collections.emptyList()).build();
interVpnLinkUtil.updateInterVpnLinkState(ivpnLinkName, InterVpnLinkState.State.Error, firstEndPointState, secondEndPointState, interVpnLinkCache);
}
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.Update in project netvirt by opendaylight.
the class ElanInterfaceManager method handleInternalTunnelStateEvent.
@SuppressWarnings("checkstyle:IllegalCatch")
public void handleInternalTunnelStateEvent(Uint64 srcDpId, Uint64 dstDpId) {
ElanDpnInterfaces dpnInterfaceLists = elanUtils.getElanDpnInterfacesList();
LOG.trace("processing tunnel state event for srcDpId {} dstDpId {}" + " and dpnInterfaceList {}", srcDpId, dstDpId, dpnInterfaceLists);
if (dpnInterfaceLists == null) {
return;
}
Map<ElanDpnInterfacesListKey, ElanDpnInterfacesList> elanDpnIf = dpnInterfaceLists.nonnullElanDpnInterfacesList();
for (ElanDpnInterfacesList elanDpns : elanDpnIf.values()) {
int cnt = 0;
String elanName = elanDpns.getElanInstanceName();
ElanInstance elanInfo = elanInstanceCache.get(elanName).orElse(null);
if (elanInfo == null) {
LOG.warn("ELAN Info is null for elanName {} that does exist in elanDpnInterfaceList, " + "skipping this ELAN for tunnel handling", elanName);
continue;
}
if (!isVxlanNetworkOrVxlanSegment(elanInfo)) {
LOG.debug("Ignoring internal tunnel state event for Flat/Vlan elan {}", elanName);
continue;
}
Map<DpnInterfacesKey, DpnInterfaces> dpnInterfaces = elanDpns.nonnullDpnInterfaces();
if (dpnInterfaces == null) {
continue;
}
DpnInterfaces dstDpnIf = null;
for (DpnInterfaces dpnIf : dpnInterfaces.values()) {
Uint64 dpnIfDpId = dpnIf.getDpId();
if (Objects.equals(dpnIfDpId, srcDpId)) {
cnt++;
} else if (Objects.equals(dpnIfDpId, dstDpId)) {
cnt++;
dstDpnIf = dpnIf;
}
}
if (cnt == 2) {
LOG.info("Elan instance:{} is present b/w srcDpn:{} and dstDpn:{}", elanName, srcDpId, dstDpId);
// var needs to be final so it can be accessed in lambda
final DpnInterfaces finalDstDpnIf = dstDpnIf;
jobCoordinator.enqueueJob(elanName, () -> {
// update Remote BC Group
LOG.trace("procesing elan remote bc group for tunnel event {}", elanInfo);
try {
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);
}
Set<String> interfaceLists = new HashSet<>();
interfaceLists.addAll(finalDstDpnIf.getInterfaces());
for (String ifName : interfaceLists) {
jobCoordinator.enqueueJob(ElanUtils.getElanInterfaceJobKey(ifName), () -> {
LOG.info("Processing tunnel up event for elan {} and interface {}", elanName, ifName);
InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(ifName);
if (isOperational(interfaceInfo)) {
return installDMacAddressTables(elanInfo, interfaceInfo, srcDpId);
}
return emptyList();
}, ElanConstants.JOB_MAX_RETRIES);
}
return emptyList();
}, ElanConstants.JOB_MAX_RETRIES);
}
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.Update in project netvirt by opendaylight.
the class ElanInterfaceStateClusteredListener method handleExternalTunnelUpdate.
private void handleExternalTunnelUpdate(String interfaceName, Interface update) {
ExternalTunnel externalTunnel = elanUtils.getExternalTunnel(interfaceName, LogicalDatastoreType.CONFIGURATION);
if (externalTunnel != null) {
LOG.debug("handling external tunnel update event for ext device dst {} src {} ", externalTunnel.getDestinationDevice(), externalTunnel.getSourceDevice());
elanInterfaceManager.handleExternalTunnelStateEvent(externalTunnel, update);
} else {
LOG.trace("External tunnel not found with interfaceName: {}", interfaceName);
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.Update 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)));
});
}
Aggregations