use of org.opendaylight.yangtools.yang.common.Uint32 in project netvirt by opendaylight.
the class BaseVrfEntryHandler method programRemoteFib.
// Allow deprecated TransactionRunner calls for now
@SuppressWarnings("ForbidCertainMethod")
public void programRemoteFib(final Uint64 remoteDpnId, final Uint32 vpnId, final VrfEntry vrfEntry, WriteTransaction tx, String rd, List<AdjacencyResult> adjacencyResults, @Nullable List<SubTransaction> subTxns) {
if (upgradeState.isUpgradeInProgress()) {
InstanceIdentifier<Interface> absentInterfaceStateIid = getFirstAbsentInterfaceStateIid(adjacencyResults);
if (absentInterfaceStateIid != null) {
LOG.info("programRemoteFib: interface state for {} not yet present, waiting...", absentInterfaceStateIid);
eventCallbacks.onAddOrUpdate(LogicalDatastoreType.OPERATIONAL, absentInterfaceStateIid, (before, after) -> {
LOG.info("programRemoteFib: waited for and got interface state {}", absentInterfaceStateIid);
LoggingFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(Datastore.CONFIGURATION, (wtx) -> programRemoteFib(remoteDpnId, vpnId, vrfEntry, TransactionAdapter.toWriteTransaction(wtx), rd, adjacencyResults, null)), LOG, "Failed to program remote FIB {}", absentInterfaceStateIid);
return DataTreeEventCallbackRegistrar.NextAction.UNREGISTER;
}, Duration.of(15, ChronoUnit.MINUTES), (iid) -> {
LOG.error("programRemoteFib: timed out waiting for {}", absentInterfaceStateIid);
LoggingFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(Datastore.CONFIGURATION, (wtx) -> programRemoteFib(remoteDpnId, vpnId, vrfEntry, TransactionAdapter.toWriteTransaction(wtx), rd, adjacencyResults, null)), LOG, "Failed to program timed-out remote FIB {}", absentInterfaceStateIid);
});
return;
}
}
List<InstructionInfo> instructions = new ArrayList<>();
for (AdjacencyResult adjacencyResult : adjacencyResults) {
List<ActionInfo> actionInfos = new ArrayList<>();
String egressInterface = adjacencyResult.getInterfaceName();
if (FibUtil.isTunnelInterface(adjacencyResult)) {
addTunnelInterfaceActions(adjacencyResult, vpnId, vrfEntry, actionInfos, rd);
} else {
addRewriteDstMacAction(vpnId, vrfEntry, null, actionInfos);
}
List<ActionInfo> egressActions = nextHopManager.getEgressActionsForInterface(egressInterface, actionInfos.size(), true, vpnId, vrfEntry.getDestPrefix());
if (egressActions.isEmpty()) {
LOG.error("Failed to retrieve egress action for prefix {} route-paths {} interface {}. " + "Aborting remote FIB entry creation.", vrfEntry.getDestPrefix(), new ArrayList<RoutePaths>(vrfEntry.nonnullRoutePaths().values()), egressInterface);
return;
}
actionInfos.addAll(egressActions);
instructions.add(new InstructionApplyActions(actionInfos));
}
makeConnectedRoute(remoteDpnId, vpnId, vrfEntry, rd, instructions, NwConstants.ADD_FLOW, tx, subTxns);
}
use of org.opendaylight.yangtools.yang.common.Uint32 in project netvirt by opendaylight.
the class BaseVrfEntryHandler method addTunnelInterfaceActions.
protected void addTunnelInterfaceActions(AdjacencyResult adjacencyResult, Uint32 vpnId, VrfEntry vrfEntry, List<ActionInfo> actionInfos, String rd) {
Class<? extends TunnelTypeBase> tunnelType = VpnExtraRouteHelper.getTunnelType(nextHopManager.getItmManager(), adjacencyResult.getInterfaceName());
if (tunnelType == null) {
LOG.debug("Tunnel type not found for vrfEntry {}", vrfEntry);
return;
}
// TODO - For now have added routePath into adjacencyResult so that we know for which
// routePath this result is built for. If this is not possible construct a map which does
// the same.
String nextHopIp = adjacencyResult.getNextHopIp();
java.util.Optional<Uint32> optionalLabel = FibUtil.getLabelForNextHop(vrfEntry, nextHopIp);
if (!optionalLabel.isPresent()) {
LOG.warn("NextHopIp {} not found in vrfEntry {}", nextHopIp, vrfEntry);
return;
}
Uint32 label = optionalLabel.get();
Uint64 tunnelId = null;
Prefixes prefixInfo = null;
// revisit
if (tunnelType.equals(TunnelTypeVxlan.class)) {
if (FibHelper.isControllerManagedNonSelfImportedRoute(RouteOrigin.value(vrfEntry.getOrigin()))) {
prefixInfo = fibUtil.getPrefixToInterface(vpnId, vrfEntry.getDestPrefix());
// For extra route, the prefixInfo is fetched from the primary adjacency
if (prefixInfo == null) {
prefixInfo = fibUtil.getPrefixToInterface(vpnId, adjacencyResult.getPrefix());
}
} else {
// Imported Route. Get Prefix Info from parent RD
VpnInstanceOpDataEntry parentVpn = fibUtil.getVpnInstance(vrfEntry.getParentVpnRd());
prefixInfo = fibUtil.getPrefixToInterface(parentVpn.getVpnId(), adjacencyResult.getPrefix());
}
// Internet VPN VNI will be used as tun_id for NAT use-cases
if (Prefixes.PrefixCue.Nat.equals(prefixInfo.getPrefixCue())) {
if (vrfEntry.getL3vni() != null && vrfEntry.getL3vni().toJava() != 0) {
tunnelId = Uint64.valueOf(vrfEntry.getL3vni().longValue());
}
} else {
if (FibUtil.isVxlanNetwork(prefixInfo.getNetworkType())) {
tunnelId = Uint64.valueOf(prefixInfo.getSegmentationId().longValue());
} else {
LOG.warn("Network is not of type VXLAN for prefix {}." + "Going with default Lport Tag.", prefixInfo.toString());
tunnelId = Uint64.valueOf(label.longValue());
}
}
} else {
tunnelId = Uint64.valueOf(label.longValue());
}
LOG.debug("adding set tunnel id action for label {}", label);
actionInfos.add(new ActionSetFieldTunnelId(tunnelId));
addRewriteDstMacAction(vpnId, vrfEntry, prefixInfo, actionInfos);
}
use of org.opendaylight.yangtools.yang.common.Uint32 in project netvirt by opendaylight.
the class BaseVrfEntryHandler method resolveAdjacency.
@NonNull
protected List<AdjacencyResult> resolveAdjacency(final Uint64 remoteDpnId, final Uint32 vpnId, final VrfEntry vrfEntry, String rd) {
List<RoutePaths> routePaths = new ArrayList<RoutePaths>(vrfEntry.nonnullRoutePaths().values());
FibHelper.sortIpAddress(routePaths);
List<AdjacencyResult> adjacencyList = new ArrayList<>();
List<String> prefixIpList;
LOG.trace("resolveAdjacency called with remotedDpnId {}, vpnId{}, VrfEntry {}", remoteDpnId, vpnId, vrfEntry);
final Class<? extends TunnelTypeBase> tunnelType;
try {
if (RouteOrigin.value(vrfEntry.getOrigin()) != RouteOrigin.BGP) {
tunnelType = TunnelTypeVxlan.class;
List<String> usedRds = VpnExtraRouteHelper.getUsedRds(dataBroker, vpnId, vrfEntry.getDestPrefix());
List<Routes> vpnExtraRoutes = VpnExtraRouteHelper.getAllVpnExtraRoutes(dataBroker, fibUtil.getVpnNameFromId(vpnId), usedRds, vrfEntry.getDestPrefix());
if (vpnExtraRoutes.isEmpty()) {
Prefixes prefixInfo = fibUtil.getPrefixToInterface(vpnId, vrfEntry.getDestPrefix());
/* We don't want to provide an adjacencyList for
* (1) an extra-route-prefix or,
* (2) for a local route without prefix-to-interface.
* Allow only self-imported routes in such cases */
if (prefixInfo == null && FibHelper.isControllerManagedNonSelfImportedRoute(RouteOrigin.value(vrfEntry.getOrigin()))) {
LOG.debug("The prefix {} in rd {} for vpn {} does not have a valid extra-route or" + " prefix-to-interface entry in the data-store", vrfEntry.getDestPrefix(), rd, vpnId);
return adjacencyList;
}
prefixIpList = Collections.singletonList(vrfEntry.getDestPrefix());
} else {
List<String> prefixIpListLocal = new ArrayList<>();
vpnExtraRoutes.stream().filter(route -> route.getNexthopIpList() != null).forEach(route -> route.getNexthopIpList().forEach(extraRouteIp -> {
String ipPrefix;
if (isIpv4Address(extraRouteIp)) {
ipPrefix = extraRouteIp + NwConstants.IPV4PREFIX;
} else {
ipPrefix = extraRouteIp + NwConstants.IPV6PREFIX;
}
prefixIpListLocal.add(ipPrefix);
}));
prefixIpList = prefixIpListLocal;
}
} else {
prefixIpList = Collections.singletonList(vrfEntry.getDestPrefix());
if (vrfEntry.getEncapType() == VrfEntry.EncapType.Mplsgre) {
tunnelType = TunnelTypeMplsOverGre.class;
} else {
tunnelType = TunnelTypeVxlan.class;
}
}
for (String prefixIp : prefixIpList) {
if (routePaths == null || routePaths.isEmpty()) {
LOG.trace("Processing Destination IP {} without NextHop IP", prefixIp);
AdjacencyResult adjacencyResult = nextHopManager.getRemoteNextHopPointer(remoteDpnId, vpnId, prefixIp, null, tunnelType);
addAdjacencyResultToList(adjacencyList, adjacencyResult);
continue;
}
adjacencyList.addAll(routePaths.stream().map(routePath -> {
LOG.debug("NextHop IP for destination {} is {}", prefixIp, routePath.getNexthopAddress());
return nextHopManager.getRemoteNextHopPointer(remoteDpnId, vpnId, prefixIp, routePath.getNexthopAddress(), tunnelType);
}).filter(adjacencyResult -> adjacencyResult != null && !adjacencyList.contains(adjacencyResult)).distinct().collect(toList()));
}
} catch (NullPointerException e) {
// FIXME: NPEs should not be caught but rather their root cause should be eliminated
LOG.trace("Failed to remove adjacency", e);
}
return adjacencyList;
}
use of org.opendaylight.yangtools.yang.common.Uint32 in project netvirt by opendaylight.
the class EvpnVrfEntryHandler method createFlows.
void createFlows(InstanceIdentifier<VrfEntry> identifier, VrfEntry vrfEntry, String rd) {
LOG.info("Initiating creation of Evpn Flows");
final VrfTablesKey vrfTableKey = identifier.firstKeyOf(VrfTables.class);
final VpnInstanceOpDataEntry vpnInstance = getFibUtil().getVpnInstanceOpData(vrfTableKey.getRouteDistinguisher()).get();
Uint32 vpnId = vpnInstance.getVpnId();
checkNotNull(vpnInstance, "Vpn Instance not available %s", vrfTableKey.getRouteDistinguisher());
checkNotNull(vpnId, "Vpn Instance with rd %s has null vpnId!", vpnInstance.getVrfId());
if (RouteOrigin.value(vrfEntry.getOrigin()) == RouteOrigin.CONNECTED) {
SubnetRoute subnetRoute = vrfEntry.augmentation(SubnetRoute.class);
final Map<VpnToDpnListKey, VpnToDpnList> keyVpnToDpnListMap = vpnInstance.nonnullVpnToDpnList();
final long elanTag = subnetRoute.getElantag().toJava();
LOG.trace("SubnetRoute augmented vrfentry found for rd {} prefix {} with elantag {}", rd, vrfEntry.getDestPrefix(), elanTag);
if (keyVpnToDpnListMap != null) {
jobCoordinator.enqueueJob("FIB-" + rd + "-" + vrfEntry.getDestPrefix(), () -> Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
for (final VpnToDpnList curDpn : keyVpnToDpnListMap.values()) {
if (curDpn.getDpnState() == VpnToDpnList.DpnState.Active) {
vrfEntryListener.installSubnetRouteInFib(curDpn.getDpnId(), elanTag, rd, vpnId, vrfEntry, tx);
}
}
})));
}
return;
}
Prefixes localNextHopInfo = getFibUtil().getPrefixToInterface(vpnInstance.getVpnId(), vrfEntry.getDestPrefix());
List<Uint64> localDpnId = new ArrayList<>();
boolean isNatPrefix = false;
if (Prefixes.PrefixCue.Nat.equals(localNextHopInfo.getPrefixCue())) {
LOG.info("NAT Prefix {} with vpnId {} rd {}. Skip local dpn {} FIB processing", vrfEntry.getDestPrefix(), vpnId, rd, localNextHopInfo.getDpnId());
localDpnId.add(localNextHopInfo.getDpnId());
isNatPrefix = true;
} else {
localDpnId = createLocalEvpnFlows(vpnInstance.getVpnId(), rd, vrfEntry, localNextHopInfo);
}
createRemoteEvpnFlows(rd, vrfEntry, vpnInstance, localDpnId, vrfTableKey, isNatPrefix);
}
use of org.opendaylight.yangtools.yang.common.Uint32 in project netvirt by opendaylight.
the class BgpManagerTestImpl method addPrefix.
public void addPrefix(String rd, String macAddress, String pfx, List<String> nhList, VrfEntry.EncapType encapType, Uint32 lbl, Uint32 l3vni, Uint32 l2vni, String gatewayMac) throws TransactionCommitFailedException {
for (String nh : nhList) {
Ipv4Address nexthop = nh != null ? new Ipv4Address(nh) : null;
Uint32 label = lbl;
InstanceIdentifier<Networks> iid = InstanceIdentifier.builder(Bgp.class).child(NetworksContainer.class).child(Networks.class, new NetworksKey(pfx, rd)).build();
NetworksBuilder networksBuilder = new NetworksBuilder().setRd(rd).setPrefixLen(pfx).setNexthop(nexthop).setLabel(label).setEthtag(Uint32.ZERO);
buildVpnEncapSpecificInfo(networksBuilder, encapType, label, l3vni, l2vni, macAddress, gatewayMac);
singleTxdataBroker.syncWrite(LogicalDatastoreType.CONFIGURATION, iid, networksBuilder.build());
}
}
Aggregations