import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
if (localDpnId != null && localDpnId != BigInteger.ZERO) {
// localDpnId is not known when clean up happens for last vm for a vpn on a dpn
if (extraRouteOptional.isPresent()) {
- nexthopManager.setupLoadBalancingNextHop(vpnId, remoteDpnId, vrfEntry.getDestPrefix(),
- Collections.emptyList() /*listBucketInfo*/ , false);
+ nexthopManager.deleteLoadBalancingNextHop(vpnId, remoteDpnId, vrfEntry.getDestPrefix());
}
deleteFibEntryForBgpRoutes(remoteDpnId, vpnId, vrfEntry, rd, tx, subTxns);
return;
// below two reads are kept as is, until best way is found to identify dpnID
VpnNexthop localNextHopInfo = nexthopManager.getVpnNexthop(vpnId, vrfEntry.getDestPrefix());
if (extraRouteOptional.isPresent()) {
- nexthopManager.setupLoadBalancingNextHop(vpnId, remoteDpnId, vrfEntry.getDestPrefix(),
- Collections.emptyList() /*listBucketInfo*/ , false);
+ nexthopManager.deleteLoadBalancingNextHop(vpnId, remoteDpnId, vrfEntry.getDestPrefix());
} else {
checkDpnDeleteFibEntry(localNextHopInfo, remoteDpnId, vpnId, vrfEntry, rd, tx, subTxns);
}
return "nexthop." + vpnId + ipAddress;
}
+ String getRemoteSelectGroupKey(long vpnId, String ipAddress) {
+ return "remote.ecmp.nexthop." + vpnId + ipAddress;
+ }
+
+ String getLocalSelectGroupKey(long vpnId, String ipAddress) {
+ return "local.ecmp.nexthop." + vpnId + ipAddress;
+ }
+
public ItmRpcService getItmManager() {
return itmManager;
}
return groupId;
}
+ public long getLocalSelectGroup(long vpnId,
+ String ipNextHopAddress) {
+ long groupId = createNextHopPointer(getLocalSelectGroupKey(vpnId, ipNextHopAddress));
+ if (groupId == FibConstants.INVALID_GROUP_ID) {
+ LOG.error("Unable to allocate groupId for vpnId {} , prefix {}", vpnId, ipNextHopAddress);
+ }
+ return groupId;
+ }
+
public long createLocalNextHop(long vpnId, BigInteger dpnId, String ifName,
String primaryIpAddress, String currDestIpPrefix,
String gwMacAddress) {
}
protected long setupLoadBalancingNextHop(Long parentVpnId, BigInteger dpnId,
- String destPrefix, List<BucketInfo> listBucketInfo, boolean addOrRemove) {
- long groupId = createNextHopPointer(getNextHopKey(parentVpnId, destPrefix));
- if (groupId == FibConstants.INVALID_GROUP_ID) {
- LOG.error("Unable to allocate/retrieve groupId for vpnId {} , prefix {}", parentVpnId, destPrefix);
- return groupId;
+ String destPrefix, List<BucketInfo> localBucketInfo, List<BucketInfo> remoteBucketInfo) {
+ long remoteGroupId = createNextHopPointer(getRemoteSelectGroupKey(parentVpnId, destPrefix));
+ if (remoteGroupId == FibConstants.INVALID_GROUP_ID) {
+ LOG.error("Unable to allocate/retrieve remote groupId for vpnId {} , prefix {}", parentVpnId, destPrefix);
+ return remoteGroupId;
+ }
+ long localGroupId = FibConstants.INVALID_GROUP_ID;
+ if (!localBucketInfo.isEmpty() && !remoteBucketInfo.isEmpty()) {
+ localGroupId = createNextHopPointer(getLocalSelectGroupKey(parentVpnId, destPrefix));
+ if (localGroupId == FibConstants.INVALID_GROUP_ID) {
+ LOG.error("Unable to allocate/retrieve local groupId for vpnId {} , prefix {}",
+ parentVpnId, destPrefix);
+ return remoteGroupId;
+ }
}
- GroupEntity groupEntity = MDSALUtil.buildGroupEntity(
- dpnId, groupId, destPrefix, GroupTypes.GroupSelect, listBucketInfo);
+ List<BucketInfo> combinedBucketInfo = new ArrayList<>();
+ combinedBucketInfo.addAll(localBucketInfo);
+ combinedBucketInfo.addAll(remoteBucketInfo);
+ GroupEntity remoteGroupEntity = MDSALUtil.buildGroupEntity(
+ dpnId, remoteGroupId, destPrefix, GroupTypes.GroupSelect, combinedBucketInfo);
+ GroupEntity localGroupEntity = MDSALUtil.buildGroupEntity(
+ dpnId, localGroupId, destPrefix, GroupTypes.GroupSelect, localBucketInfo);
String jobKey = FibUtil.getCreateLocalNextHopJobKey(parentVpnId, dpnId, destPrefix);
jobCoordinator.enqueueJob(jobKey, () -> {
- if (addOrRemove) {
- mdsalApiManager.syncInstallGroup(groupEntity);
- if (LOG.isDebugEnabled()) {
- LOG.debug("Finished installing GroupEntity with jobCoordinator key {} groupEntity.groupId {}"
- + " groupEntity.groupType {}", jobKey, groupEntity.getGroupId(),
- groupEntity.getGroupType());
- }
- } else {
- mdsalApiManager.removeGroup(groupEntity);
- if (LOG.isDebugEnabled()) {
- LOG.debug("Finished removing GroupEntity with jobCoordinator key {} groupEntity.groupId {}"
- + " groupEntity.groupType {}", jobKey, groupEntity.getGroupId(),
- groupEntity.getGroupType());
- }
+ mdsalApiManager.syncInstallGroup(remoteGroupEntity);
+ if (!localBucketInfo.isEmpty() && !remoteBucketInfo.isEmpty()) {
+ mdsalApiManager.syncInstallGroup(localGroupEntity);
+ }
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Finished installing GroupEntity with jobCoordinator key {} remoteGroupEntity.groupId {}"
+ + "localGroupEntity.groupId {} groupEntity.groupType {}", jobKey,
+ remoteGroupEntity.getGroupId(), localGroupEntity.getGroupId(),
+ remoteGroupEntity.getGroupType());
+ }
+ return Collections.emptyList();
+ });
+ return remoteGroupId;
+ }
+
+ protected void deleteLoadBalancingNextHop(Long parentVpnId, BigInteger dpnId, String destPrefix) {
+ long remoteGroupId = createNextHopPointer(getRemoteSelectGroupKey(parentVpnId, destPrefix));
+ if (remoteGroupId == FibConstants.INVALID_GROUP_ID) {
+ LOG.error("Unable to allocate/retrieve remote groupId for vpnId {} , prefix {}", parentVpnId, destPrefix);
+ }
+ long localGroupId = createNextHopPointer(getLocalSelectGroupKey(parentVpnId, destPrefix));
+ if (localGroupId == FibConstants.INVALID_GROUP_ID) {
+ LOG.error("Unable to allocate/retrieve local groupId for vpnId {} , prefix {}", parentVpnId, destPrefix);
+ }
+ String jobKey = FibUtil.getCreateLocalNextHopJobKey(parentVpnId, dpnId, destPrefix);
+ jobCoordinator.enqueueJob(jobKey, () -> {
+ mdsalApiManager.removeGroup(dpnId, remoteGroupId);
+ mdsalApiManager.removeGroup(dpnId, localGroupId);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Finished removing GroupEntity with jobCoordinator key {} remoteGroupEntity.groupId {}"
+ + "localGroupEntity.groupId {}", jobKey, remoteGroupId, localGroupId);
}
return Collections.emptyList();
});
- return groupId;
}
long createNextHopGroups(Long vpnId, String rd, BigInteger dpnId, VrfEntry vrfEntry,
Routes routes, List<Routes> vpnExtraRoutes) {
- List<BucketInfo> listBucketInfo = new ArrayList<>();
+ List<BucketInfo> localBucketInfo = new ArrayList<>();
List<Routes> clonedVpnExtraRoutes = new ArrayList<>(vpnExtraRoutes);
if (clonedVpnExtraRoutes.contains(routes)) {
- listBucketInfo.addAll(getBucketsForLocalNexthop(vpnId, dpnId, vrfEntry, routes));
+ localBucketInfo.addAll(getBucketsForLocalNexthop(vpnId, dpnId, vrfEntry, routes));
clonedVpnExtraRoutes.remove(routes);
}
- listBucketInfo.addAll(getBucketsForRemoteNexthop(vpnId, dpnId, vrfEntry, rd, clonedVpnExtraRoutes));
- return setupLoadBalancingNextHop(vpnId, dpnId, vrfEntry.getDestPrefix(), listBucketInfo,true);
+ List<BucketInfo> remoteBucketInfo = new ArrayList<>();
+ remoteBucketInfo.addAll(getBucketsForRemoteNexthop(vpnId, dpnId, vrfEntry, rd, clonedVpnExtraRoutes));
+ return setupLoadBalancingNextHop(vpnId, dpnId,
+ vrfEntry.getDestPrefix(), localBucketInfo, remoteBucketInfo);
}
private List<BucketInfo> getBucketsForLocalNexthop(Long vpnId, BigInteger dpnId,
}
if (vpnExtraRoutes.size() > 1) {
groupId = nextHopManager.createNextHopGroups(vpnId, rd, dpnId, vrfEntry, routes, vpnExtraRoutes);
- localGroupId = nextHopManager.getLocalNextHopGroup(vpnId, localNextHopIP);
+ localGroupId = nextHopManager.getLocalSelectGroup(vpnId, vrfEntry.getDestPrefix());
} else if (routes.getNexthopIpList().size() > 1) {
groupId = nextHopManager.createNextHopGroups(vpnId, rd, dpnId, vrfEntry, routes, vpnExtraRoutes);
localGroupId = groupId;
Collections.singletonList(new ActionGroup(groupId))));
final List<InstructionInfo> lfibinstructions = Collections.singletonList(
new InstructionApplyActions(
- Arrays.asList(new ActionPopMpls(etherType), new ActionGroup(groupId))));
+ Arrays.asList(new ActionPopMpls(etherType), new ActionGroup(localGroupId))));
java.util.Optional<Long> optLabel = FibUtil.getLabelFromRoutePaths(vrfEntry);
List<String> nextHopAddressList = FibHelper.getNextHopListFromRoutePaths(vrfEntry);
String jobKey = FibUtil.getCreateLocalNextHopJobKey(vpnId, dpnId, vrfEntry.getDestPrefix());
nextHopAddressList);
makeLFibTableEntry(dpnId, label, lfibinstructions, DEFAULT_FIB_FLOW_PRIORITY,
NwConstants.ADD_FLOW, tx);
- // If the extra-route is reachable from VMs attached to the same switch,
- // then the tunnel table can point to the load balancing group.
- // If it is reachable from VMs attached to different switches,
- // then it should be pointing to one of the local group in order to avoid looping.
- if (vrfEntry.getRoutePaths().size() == 1) {
- makeTunnelTableEntry(dpnId, label, groupId, tx);
- } else {
- makeTunnelTableEntry(dpnId, label, localGroupId, tx);
- }
+ makeTunnelTableEntry(dpnId, label, localGroupId, tx);
} else {
LOG.debug("Route with rd {} prefix {} label {} nexthop {} for vpn {} is an imported "
+ "route. LFib and Terminating table entries will not be created.",
vrfEntry, shouldUpdateNonEcmpLocalNextHop);
if (!dpnId.equals(BigInteger.ZERO)) {
LOG.trace("Deleting ECMP group for prefix {}, dpn {}", vrfEntry.getDestPrefix(), dpnId);
- nextHopManager.setupLoadBalancingNextHop(vpnId, dpnId,
- vrfEntry.getDestPrefix(), /*listBucketInfo*/ Collections.emptyList(),
- /*remove*/ false);
+ nextHopManager.deleteLoadBalancingNextHop(vpnId, dpnId, vrfEntry.getDestPrefix());
returnLocalDpnId.add(dpnId);
}
} else {
vrfEntry.getDestPrefix()));
txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, configTx ->
configTx.delete(VpnExtraRouteHelper.getUsedRdsIdentifier(vpnId, vrfEntry.getDestPrefix())));
+ nextHopManager.removeNextHopPointer(nextHopManager
+ .getRemoteSelectGroupKey(vpnId, vrfEntry.getDestPrefix()));
+ nextHopManager.removeNextHopPointer(nextHopManager
+ .getLocalSelectGroupKey(vpnId, vrfEntry.getDestPrefix()));
}
}
handleAdjacencyAndVpnOpInterfaceDeletion(vrfEntry, ifName, vpnName, tx);