use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentrybase.RoutePaths in project netvirt by opendaylight.
the class FibEntriesListener method addLabelToVpnInstance.
private void addLabelToVpnInstance(String rd, List<RoutePaths> routePaths) {
List<Long> labels = routePaths.stream().map(RoutePaths::getLabel).distinct().collect(Collectors.toList());
VpnInstanceOpDataEntry vpnInstanceOpData = vpnInstanceListener.getVpnInstanceOpData(rd);
if (vpnInstanceOpData != null) {
List<Long> routeIds = vpnInstanceOpData.getRouteEntryId() == null ? new ArrayList<>() : vpnInstanceOpData.getRouteEntryId();
labels.forEach(label -> {
LOG.debug("Adding label to vpn info - {}", label);
if (!routeIds.contains(label)) {
routeIds.add(label);
}
});
TransactionUtil.asyncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, VpnUtil.getVpnInstanceOpDataIdentifier(rd), new VpnInstanceOpDataEntryBuilder(vpnInstanceOpData).setRouteEntryId(routeIds).build(), TransactionUtil.DEFAULT_CALLBACK);
} else {
LOG.warn("No VPN Instance found for RD: {}", rd);
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentrybase.RoutePaths in project netvirt by opendaylight.
the class VPNServiceChainHandlerTest method testProgramVpnToScfWithVpnIfacesAlreadyBound.
@Test
public void testProgramVpnToScfWithVpnIfacesAlreadyBound() throws Exception {
// ///////////////////
// Basic stubbing //
// ///////////////////
String ifaceName = "eth0";
stubGetRouteDistinguisher(VPN_NAME, RD);
stubGetVpnInstance(RD, "1.2.3.4", ifaceName);
VrfEntry vrfEntry = FibHelper.getVrfEntryBuilder("11.12.13.14", 2000L, DC_GW_IP, RouteOrigin.STATIC, null).build();
stubGetVrfEntries(RD, Collections.singletonList(vrfEntry));
stubReadVpnToDpnList(RD, DPN_ID, Collections.singletonList(ifaceName));
stubScfIsBoundOnIface(SCF_TAG, ifaceName);
// ///////
// SUT //
// ///////
short tableId = 10;
vpnsch.programVpnToScfPipeline(VPN_NAME, tableId, SCF_TAG, LPORT_TAG, NwConstants.ADD_FLOW);
// //////////
// Verify //
// //////////
ArgumentCaptor<FlowEntity> argumentCaptor = ArgumentCaptor.forClass(FlowEntity.class);
verify(mdsalMgr, times(2)).installFlow(argumentCaptor.capture());
List<FlowEntity> installedFlowsCaptured = argumentCaptor.getAllValues();
assert installedFlowsCaptured.size() == 2;
RoutePaths routePath = vrfEntry.getRoutePaths().get(0);
FlowEntity expectedLFibFlowEntity = VpnServiceChainUtils.buildLFibVpnPseudoPortFlow(DPN_ID, routePath.getLabel(), routePath.getNexthopAddress(), LPORT_TAG);
assert new FlowEntityMatcher(expectedLFibFlowEntity).matches(installedFlowsCaptured.get(0));
FlowEntity expectedLPortDispatcher = VpnServiceChainUtils.buildLportFlowDispForVpnToScf(DPN_ID, LPORT_TAG, SCF_TAG, tableId);
assert new FlowEntityMatcher(expectedLPortDispatcher).matches(installedFlowsCaptured.get(1));
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentrybase.RoutePaths in project netvirt by opendaylight.
the class FibUtil method removeOrUpdateFibEntry.
/**
* Removes a specific Nexthop from a VrfEntry. If Nexthop to remove is the
* last one in the VrfEntry, then the VrfEntry is removed too.
* @param rd Route-Distinguisher to which the VrfEntry belongs to
* @param prefix Destination of the route
* @param nextHopToRemove Specific nexthop within the Route to be removed.
* If null or empty, then the whole VrfEntry is removed
*/
public void removeOrUpdateFibEntry(String rd, String prefix, String nextHopToRemove, WriteTransaction writeConfigTxn) {
LOG.debug("Removing fib entry with destination prefix {} from vrf table for rd {} nextHop {}", prefix, rd, nextHopToRemove);
// Looking for existing prefix in MDSAL database
InstanceIdentifier<VrfEntry> vrfEntryId = InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)).child(VrfEntry.class, new VrfEntryKey(prefix)).build();
Optional<VrfEntry> entry = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, vrfEntryId);
if (entry.isPresent()) {
final List<RoutePaths> routePaths = entry.get().getRoutePaths();
if (routePaths == null || routePaths.isEmpty()) {
LOG.warn("routePaths is null/empty for given rd {}, prefix {}", rd, prefix);
return;
}
java.util.Optional<RoutePaths> optRoutePath = routePaths.stream().filter(routePath -> routePath.getNexthopAddress().equals(nextHopToRemove)).findFirst();
if (!optRoutePath.isPresent()) {
LOG.error("Unable to find a routePath that contains the given nextHop to remove {}", nextHopToRemove);
return;
}
RoutePaths routePath = optRoutePath.get();
if (routePaths.size() == 1) {
// Remove the whole entry
if (writeConfigTxn != null) {
writeConfigTxn.delete(LogicalDatastoreType.CONFIGURATION, vrfEntryId);
} else {
MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, vrfEntryId);
}
LOG.info("Removed Fib Entry rd {} prefix {} nextHop {}", rd, prefix, nextHopToRemove);
} else {
InstanceIdentifier<RoutePaths> routePathsId = FibHelper.buildRoutePathId(rd, prefix, routePath.getNexthopAddress());
// Remove route
MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, routePathsId);
LOG.info("Removed Route Path rd {} prefix {}, nextHop {}, label {}", rd, prefix, routePath.getNexthopAddress(), routePath.getLabel());
}
} else {
LOG.warn("Could not find VrfEntry for Route-Distinguisher {} prefix {} nexthop {}", rd, prefix, nextHopToRemove);
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentrybase.RoutePaths in project netvirt by opendaylight.
the class VrfEntryListener method update.
@Override
// originalRoutePath is a little dicey - safest to keep the checking even if not needed.
@SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE")
protected void update(InstanceIdentifier<VrfEntry> identifier, VrfEntry original, VrfEntry update) {
Preconditions.checkNotNull(update, "VrfEntry should not be null or empty.");
final String rd = identifier.firstKeyOf(VrfTables.class).getRouteDistinguisher();
LOG.debug("UPDATE: Updating Fib Entries to rd {} prefix {} route-paths {} origin {} old-origin {}", rd, update.getDestPrefix(), update.getRoutePaths(), update.getOrigin(), original.getOrigin());
// Handle BGP Routes first
if (RouteOrigin.value(update.getOrigin()) == RouteOrigin.BGP) {
bgpRouteVrfEntryHandler.updateFlows(identifier, original, update, rd);
LOG.info("UPDATE: Updated BGP advertised Fib Entry with rd {} prefix {} route-paths {}", rd, update.getDestPrefix(), update.getRoutePaths());
return;
}
if (RouteOrigin.value(update.getOrigin()) == RouteOrigin.STATIC) {
List<RoutePaths> originalRoutePath = original.getRoutePaths();
List<RoutePaths> updateRoutePath = update.getRoutePaths();
LOG.info("UPDATE: Original route-path {} update route-path {} ", originalRoutePath, updateRoutePath);
// Updates need to be handled for extraroute even if original vrf entry route path is null or
// updated vrf entry route path is null. This can happen during tunnel events.
Optional<VpnInstanceOpDataEntry> optVpnInstance = fibUtil.getVpnInstanceOpData(rd);
List<String> usedRds = new ArrayList<>();
if (optVpnInstance.isPresent()) {
usedRds = VpnExtraRouteHelper.getUsedRds(dataBroker, optVpnInstance.get().getVpnId(), update.getDestPrefix());
}
// has nexthop , route needs to be created on remote Dpns
if (originalRoutePath == null || originalRoutePath.isEmpty() && updateRoutePath != null && !updateRoutePath.isEmpty() && usedRds.isEmpty()) {
// TODO(vivek): Though ugly, Not handling this code now, as each
// tep add event will invoke flow addition
LOG.trace("Original VRF entry NH is null for destprefix {}. And the prefix is not an extra route." + " This event is IGNORED here.", update.getDestPrefix());
return;
}
// has nexthop empty'ed out, route needs to be removed from remote Dpns
if (updateRoutePath == null || updateRoutePath.isEmpty() && originalRoutePath != null && !originalRoutePath.isEmpty() && usedRds.isEmpty()) {
LOG.trace("Original VRF entry had valid NH for destprefix {}. And the prefix is not an extra route." + "This event is IGNORED here.", update.getDestPrefix());
return;
}
// Update the used rds and vpntoextraroute containers only for the deleted nextHops.
List<String> nextHopsRemoved = FibHelper.getNextHopListFromRoutePaths(original);
nextHopsRemoved.removeAll(FibHelper.getNextHopListFromRoutePaths(update));
WriteTransaction writeOperTxn = dataBroker.newWriteOnlyTransaction();
nextHopsRemoved.parallelStream().forEach(nextHopRemoved -> fibUtil.updateUsedRdAndVpnToExtraRoute(writeOperTxn, nextHopRemoved, rd, update.getDestPrefix()));
CheckedFuture<Void, TransactionCommitFailedException> operFuture = writeOperTxn.submit();
try {
operFuture.get();
} catch (InterruptedException | ExecutionException e) {
LOG.error("Exception encountered while submitting operational future for update vrfentry {}", update, e);
}
createFibEntries(identifier, update);
LOG.info("UPDATE: Updated static Fib Entry with rd {} prefix {} route-paths {}", rd, update.getDestPrefix(), update.getRoutePaths());
return;
}
// Handle all other routes only on a cluster reboot
if (original.equals(update)) {
// Reboot use-case
createFibEntries(identifier, update);
LOG.info("UPDATE: Updated Non-static Fib Entry with rd {} prefix {} route-paths {}", rd, update.getDestPrefix(), update.getRoutePaths());
return;
}
LOG.info("UPDATE: Ignoring update for FIB entry with rd {} prefix {} route-origin {} route-paths {}", rd, update.getDestPrefix(), update.getOrigin(), update.getRoutePaths());
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentrybase.RoutePaths in project netvirt by opendaylight.
the class VrfEntryListener method installSubnetRouteInFib.
void installSubnetRouteInFib(final BigInteger dpnId, final long elanTag, final String rd, final long vpnId, final VrfEntry vrfEntry, WriteTransaction tx) {
Boolean wrTxPresent = true;
if (tx == null) {
wrTxPresent = false;
tx = dataBroker.newWriteOnlyTransaction();
}
FibUtil.getLabelFromRoutePaths(vrfEntry).ifPresent(label -> {
List<String> nextHopAddressList = FibHelper.getNextHopListFromRoutePaths(vrfEntry);
synchronized (label.toString().intern()) {
LabelRouteInfo lri = getLabelRouteInfo(label);
if (isPrefixAndNextHopPresentInLri(vrfEntry.getDestPrefix(), nextHopAddressList, lri)) {
if (RouteOrigin.value(vrfEntry.getOrigin()) == RouteOrigin.SELF_IMPORTED) {
Optional<VpnInstanceOpDataEntry> vpnInstanceOpDataEntryOptional = fibUtil.getVpnInstanceOpData(rd);
if (vpnInstanceOpDataEntryOptional.isPresent()) {
String vpnInstanceName = vpnInstanceOpDataEntryOptional.get().getVpnInstanceName();
if (!lri.getVpnInstanceList().contains(vpnInstanceName)) {
updateVpnReferencesInLri(lri, vpnInstanceName, false);
}
}
}
LOG.debug("SUBNETROUTE: installSubnetRouteInFib: Fetched labelRouteInfo for label {} interface {}" + " and got dpn {}", label, lri.getVpnInterfaceName(), lri.getDpnId());
}
}
});
final List<InstructionInfo> instructions = new ArrayList<>();
BigInteger subnetRouteMeta = BigInteger.valueOf(elanTag).shiftLeft(24).or(BigInteger.valueOf(vpnId).shiftLeft(1));
instructions.add(new InstructionWriteMetadata(subnetRouteMeta, MetaDataUtil.METADATA_MASK_SUBNET_ROUTE));
instructions.add(new InstructionGotoTable(NwConstants.L3_SUBNET_ROUTE_TABLE));
baseVrfEntryHandler.makeConnectedRoute(dpnId, vpnId, vrfEntry, rd, instructions, NwConstants.ADD_FLOW, tx, null);
if (vrfEntry.getRoutePaths() != null) {
for (RoutePaths routePath : vrfEntry.getRoutePaths()) {
if (RouteOrigin.value(vrfEntry.getOrigin()) != RouteOrigin.SELF_IMPORTED) {
List<ActionInfo> actionsInfos = new ArrayList<>();
// reinitialize instructions list for LFIB Table
final List<InstructionInfo> LFIBinstructions = new ArrayList<>();
actionsInfos.add(new ActionPopMpls());
LFIBinstructions.add(new InstructionApplyActions(actionsInfos));
LFIBinstructions.add(new InstructionWriteMetadata(subnetRouteMeta, MetaDataUtil.METADATA_MASK_SUBNET_ROUTE));
LFIBinstructions.add(new InstructionGotoTable(NwConstants.L3_SUBNET_ROUTE_TABLE));
makeLFibTableEntry(dpnId, routePath.getLabel(), LFIBinstructions, DEFAULT_FIB_FLOW_PRIORITY, NwConstants.ADD_FLOW, tx);
}
}
}
if (!wrTxPresent) {
tx.submit();
}
}
Aggregations