use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.Prefix in project netvirt by opendaylight.
the class VrfEntryListener method populateFibOnNewDpn.
public void populateFibOnNewDpn(final Uint64 dpnId, final Uint32 vpnId, final String rd, final FutureCallback<List<?>> callback) {
LOG.trace("New dpn {} for vpn {} : populateFibOnNewDpn", dpnId, rd);
jobCoordinator.enqueueJob(FibUtil.getJobKeyForVpnIdDpnId(vpnId, dpnId), () -> {
InstanceIdentifier<VrfTables> id = buildVrfId(rd);
final VpnInstanceOpDataEntry vpnInstance = fibUtil.getVpnInstance(rd);
final Optional<VrfTables> vrfTable = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
List<ListenableFuture<?>> futures = new ArrayList<>();
if (!vrfTable.isPresent()) {
LOG.info("populateFibOnNewDpn: dpn: {}: VRF Table not yet available for RD {}", dpnId, rd);
if (callback != null) {
ListenableFuture<List<Object>> listenableFuture = Futures.allAsList(futures);
Futures.addCallback(listenableFuture, callback, MoreExecutors.directExecutor());
}
return futures;
}
final ReentrantLock lock = lockFor(vpnInstance);
lock.lock();
try {
futures.add(retryingTxRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
for (final VrfEntry vrfEntry : vrfTable.get().nonnullVrfEntry().values()) {
SubnetRoute subnetRoute = vrfEntry.augmentation(SubnetRoute.class);
if (subnetRoute != null) {
long elanTag = subnetRoute.getElantag().toJava();
installSubnetRouteInFib(dpnId, elanTag, rd, vpnId, vrfEntry, tx);
installSubnetBroadcastAddrDropRule(dpnId, rd, vpnId, vrfEntry, NwConstants.ADD_FLOW, tx);
continue;
}
RouterInterface routerInt = vrfEntry.augmentation(RouterInterface.class);
if (routerInt != null) {
LOG.trace("Router augmented vrfentry found rd:{}, uuid:{}, ip:{}, mac:{}", rd, routerInt.getUuid(), routerInt.getIpAddress(), routerInt.getMacAddress());
routerInterfaceVrfEntryHandler.installRouterFibEntry(vrfEntry, dpnId, vpnId, routerInt.getIpAddress(), new MacAddress(routerInt.getMacAddress()), NwConstants.ADD_FLOW);
continue;
}
// Handle local flow creation for imports
if (RouteOrigin.value(vrfEntry.getOrigin()) == RouteOrigin.SELF_IMPORTED) {
java.util.Optional<Uint32> optionalLabel = FibUtil.getLabelFromRoutePaths(vrfEntry);
if (optionalLabel.isPresent()) {
List<String> nextHopList = FibHelper.getNextHopListFromRoutePaths(vrfEntry);
LabelRouteInfo lri = getLabelRouteInfo(optionalLabel.get());
if (isPrefixAndNextHopPresentInLri(vrfEntry.getDestPrefix(), nextHopList, lri)) {
if (Objects.equals(lri.getDpnId(), dpnId)) {
try {
int etherType = NWUtil.getEtherTypeFromIpPrefix(vrfEntry.getDestPrefix());
createLocalFibEntry(vpnId, rd, vrfEntry, etherType);
} catch (IllegalArgumentException ex) {
LOG.warn("Unable to get etherType for IP Prefix {}", vrfEntry.getDestPrefix());
}
continue;
}
}
}
}
boolean shouldCreateRemoteFibEntry = shouldCreateFibEntryForVrfAndVpnIdOnDpn(vpnId, vrfEntry, dpnId);
if (shouldCreateRemoteFibEntry) {
LOG.trace("Will create remote FIB entry for vrfEntry {} on DPN {}", vrfEntry, dpnId);
if (RouteOrigin.BGP.getValue().equals(vrfEntry.getOrigin())) {
List<SubTransaction> txnObjects = new ArrayList<>();
bgpRouteVrfEntryHandler.createRemoteFibEntry(dpnId, vpnId, vrfTable.get().getRouteDistinguisher(), vrfEntry, TransactionAdapter.toWriteTransaction(tx), txnObjects);
} else {
createRemoteFibEntry(dpnId, vpnId, vrfTable.get().getRouteDistinguisher(), vrfEntry, tx);
}
}
}
}));
if (callback != null) {
ListenableFuture<List<Object>> listenableFuture = Futures.allAsList(futures);
Futures.addCallback(listenableFuture, callback, MoreExecutors.directExecutor());
}
} finally {
lock.unlock();
}
return futures;
});
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.Prefix in project netvirt by opendaylight.
the class VrfEntryListener method createFibEntries.
private void createFibEntries(final InstanceIdentifier<VrfEntry> vrfEntryIid, final VrfEntry vrfEntry) {
final VrfTablesKey vrfTableKey = vrfEntryIid.firstKeyOf(VrfTables.class);
List<SubTransaction> txnObjects = new ArrayList<>();
final VpnInstanceOpDataEntry vpnInstance = fibUtil.getVpnInstance(vrfTableKey.getRouteDistinguisher());
checkNotNull(vpnInstance, "Vpn Instance not available %s", vrfTableKey.getRouteDistinguisher());
checkNotNull(vpnInstance.getVpnId(), "Vpn Instance with rd %s has null vpnId!", vpnInstance.getVrfId());
final Map<VpnToDpnListKey, VpnToDpnList> keyVpnToDpnListMap;
if (vrfEntry.getParentVpnRd() != null && FibHelper.isControllerManagedNonSelfImportedRoute(RouteOrigin.value(vrfEntry.getOrigin()))) {
// This block MUST BE HIT only for PNF (Physical Network Function) FIB Entries.
VpnInstanceOpDataEntry parentVpnInstance = fibUtil.getVpnInstance(vrfEntry.getParentVpnRd());
keyVpnToDpnListMap = parentVpnInstance != null ? parentVpnInstance.nonnullVpnToDpnList() : vpnInstance.getVpnToDpnList();
LOG.info("createFibEntries: Processing creation of PNF FIB entry with rd {} prefix {}", vrfEntry.getParentVpnRd(), vrfEntry.getDestPrefix());
} else {
keyVpnToDpnListMap = vpnInstance.nonnullVpnToDpnList();
}
final Uint32 vpnId = vpnInstance.getVpnId();
final String rd = vrfTableKey.getRouteDistinguisher();
SubnetRoute subnetRoute = vrfEntry.augmentation(SubnetRoute.class);
if (subnetRoute != null) {
final long elanTag = subnetRoute.getElantag().toJava();
LOG.trace("SUBNETROUTE: createFibEntries: SubnetRoute augmented vrfentry found for rd {} prefix {}" + " with elantag {}", rd, vrfEntry.getDestPrefix(), elanTag);
if (keyVpnToDpnListMap != null) {
jobCoordinator.enqueueJob(FibUtil.getJobKeyForRdPrefix(rd, vrfEntry.getDestPrefix()), () -> Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
for (final VpnToDpnList curDpn : keyVpnToDpnListMap.values()) {
if (curDpn.getDpnState() == VpnToDpnList.DpnState.Active) {
installSubnetRouteInFib(curDpn.getDpnId(), elanTag, rd, vpnId, vrfEntry, tx);
installSubnetBroadcastAddrDropRule(curDpn.getDpnId(), rd, vpnId, vrfEntry, NwConstants.ADD_FLOW, tx);
}
}
})));
}
return;
}
// Get etherType value based on the IpPrefix address family type
int etherType;
try {
etherType = NWUtil.getEtherTypeFromIpPrefix(vrfEntry.getDestPrefix());
} catch (IllegalArgumentException ex) {
LOG.error("Unable to get etherType for IP Prefix {}", vrfEntry.getDestPrefix());
return;
}
final List<Uint64> localDpnIdList = createLocalFibEntry(vpnInstance.getVpnId(), rd, vrfEntry, etherType);
if (!localDpnIdList.isEmpty() && keyVpnToDpnListMap != null) {
jobCoordinator.enqueueJob(FibUtil.getJobKeyForRdPrefix(rd, vrfEntry.getDestPrefix()), () -> Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
final ReentrantLock lock = lockFor(vpnInstance);
lock.lock();
try {
for (VpnToDpnList vpnDpn : keyVpnToDpnListMap.values()) {
if (!localDpnIdList.contains(vpnDpn.getDpnId())) {
if (vpnDpn.getDpnState() == VpnToDpnList.DpnState.Active) {
try {
if (RouteOrigin.BGP.getValue().equals(vrfEntry.getOrigin())) {
bgpRouteVrfEntryHandler.createRemoteFibEntry(vpnDpn.getDpnId(), vpnId, vrfTableKey.getRouteDistinguisher(), vrfEntry, TransactionAdapter.toWriteTransaction(tx), txnObjects);
} else {
createRemoteFibEntry(vpnDpn.getDpnId(), vpnInstance.getVpnId(), vrfTableKey.getRouteDistinguisher(), vrfEntry, tx);
}
} catch (NullPointerException e) {
LOG.error("Failed to get create remote fib flows for prefix {} ", vrfEntry.getDestPrefix(), e);
}
}
}
}
} finally {
lock.unlock();
}
})), MAX_RETRIES);
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.Prefix 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, TypedWriteTransaction<Configuration> 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 = Optional.empty();
try {
entry = SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, vrfEntryId);
} catch (ExecutionException | InterruptedException e) {
LOG.error("removeOrUpdateFibEntry: Exception while reading vrfEntry for the prefix {} rd {} nexthop {}", prefix, rd, nextHopToRemove, e);
}
if (entry.isPresent()) {
final List<RoutePaths> routePaths = new ArrayList<>(entry.get().nonnullRoutePaths().values());
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 -> Objects.equals(routePath.getNexthopAddress(), 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(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.params.xml.ns.yang.graph.rev191125.graph.topology.graph.Prefix in project netvirt by opendaylight.
the class FibUtil method addOrUpdateFibEntry.
// TODO Clean up the exception handling
@SuppressWarnings("checkstyle:IllegalCatch")
public void addOrUpdateFibEntry(String rd, String macAddress, String prefix, List<String> nextHopList, VrfEntry.EncapType encapType, Uint32 label, Uint32 l3vni, String gwMacAddress, String parentVpnRd, RouteOrigin origin, TypedWriteTransaction<Configuration> writeConfigTxn) {
if (rd == null || rd.isEmpty()) {
LOG.error("Prefix {} not associated with vpn", prefix);
return;
}
requireNonNull(nextHopList, "NextHopList can't be null");
try {
InstanceIdentifier<VrfEntry> vrfEntryId = InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)).child(VrfEntry.class, new VrfEntryKey(prefix)).build();
writeFibEntryToDs(vrfEntryId, prefix, nextHopList, label, l3vni, encapType, origin, macAddress, gwMacAddress, parentVpnRd, writeConfigTxn);
LOG.info("addOrUpdateFibEntry: Created/Updated vrfEntry for rd {} prefix {} nexthop {} label {} l3vni {}" + " origin {} encapType {}", rd, prefix, nextHopList, label, l3vni, origin, encapType);
} catch (Exception e) {
LOG.error("addOrUpdateFibEntry: rd {} prefix {} nexthop {} label {} l3vni {} origin {} encapType {}" + " error ", rd, prefix, nextHopList, label, l3vni, origin, encapType, e);
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.Prefix in project netvirt by opendaylight.
the class FibUtil method addFibEntryForRouterInterface.
@SuppressWarnings("checkstyle:IllegalCatch")
public void addFibEntryForRouterInterface(String rd, String prefix, RouterInterface routerInterface, Uint32 label, TypedWriteTransaction<Configuration> writeConfigTxn) {
if (rd == null || rd.isEmpty()) {
LOG.error("Prefix {} not associated with vpn", prefix);
return;
}
try {
InstanceIdentifier<VrfEntry> vrfEntryId = InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)).child(VrfEntry.class, new VrfEntryKey(prefix)).build();
// Filling the nextHop with dummy nextHopAddress
VrfEntry vrfEntry = FibHelper.getVrfEntryBuilder(prefix, label, FibConstants.DEFAULT_NEXTHOP_IP, RouteOrigin.LOCAL, null).addAugmentation(routerInterface).build();
if (writeConfigTxn != null) {
writeConfigTxn.mergeParentStructureMerge(vrfEntryId, vrfEntry);
} else {
MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, vrfEntryId, vrfEntry);
}
LOG.debug("Created vrfEntry for router-interface-prefix {} rd {} label {}", prefix, rd, label);
} catch (Exception e) {
LOG.error("addFibEntryForRouterInterface: prefix {} rd {} label {} error ", prefix, rd, label, e);
}
}
Aggregations