use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.NextHop in project netvirt by opendaylight.
the class VpnSubnetRouteHandler method electNewDpnForSubnetRoute.
// TODO Clean up the exception handling
@SuppressWarnings("checkstyle:IllegalCatch")
private void electNewDpnForSubnetRoute(SubnetOpDataEntryBuilder subOpBuilder, BigInteger oldDpnId, Uuid subnetId, Uuid networkId, boolean isBgpVpn) {
List<SubnetToDpn> subDpnList = null;
boolean isRouteAdvertised = false;
subDpnList = subOpBuilder.getSubnetToDpn();
String rd = subOpBuilder.getVrfId();
String subnetIp = subOpBuilder.getSubnetCidr();
String vpnName = subOpBuilder.getVpnName();
long elanTag = subOpBuilder.getElanTag();
boolean isAlternateDpnSelected = false;
long l3vni = 0;
long label = 0;
String networkName = networkId != null ? networkId.getValue() : null;
LOG.info("{} electNewDpnForSubnetRoute: Handling subnet {} subnetIp {} vpn {} rd {} TaskState {}" + " lastTaskState {}", LOGGING_PREFIX, subnetId.getValue(), subnetIp, subOpBuilder.getVpnName(), subOpBuilder.getVrfId(), subOpBuilder.getRouteAdvState(), subOpBuilder.getLastAdvState());
if (!isBgpVpn) {
// blended more better into this design.
if (VpnUtil.isL3VpnOverVxLan(subOpBuilder.getL3vni())) {
l3vni = subOpBuilder.getL3vni();
} else {
label = getLabel(rd, subnetIp);
subOpBuilder.setLabel(label);
}
isRouteAdvertised = addSubnetRouteToFib(rd, subnetIp, null, /* nhDpnId */
null, /* nhTepIp */
vpnName, elanTag, label, l3vni, subnetId, isBgpVpn, networkName);
if (isRouteAdvertised) {
subOpBuilder.setRouteAdvState(TaskState.Advertised);
} else {
LOG.error("{} electNewDpnForSubnetRoute: Unable to find TepIp for subnet {} subnetip {} vpnName {}" + " rd {}, attempt next dpn", LOGGING_PREFIX, subnetId.getValue(), subnetIp, vpnName, rd);
subOpBuilder.setRouteAdvState(TaskState.PendingAdvertise);
}
return;
}
String nhTepIp = null;
BigInteger nhDpnId = null;
Iterator<SubnetToDpn> subnetDpnIter = subDpnList.iterator();
while (subnetDpnIter.hasNext()) {
SubnetToDpn subnetToDpn = subnetDpnIter.next();
if (subnetToDpn.getDpnId().equals(oldDpnId)) {
// Is this same is as input dpnId, then ignore it
continue;
}
nhDpnId = subnetToDpn.getDpnId();
if (vpnNodeListener.isConnectedNode(nhDpnId)) {
// but does it have a TEP configured at all?
try {
nhTepIp = InterfaceUtils.getEndpointIpAddressForDPN(dataBroker, nhDpnId);
if (nhTepIp != null) {
isAlternateDpnSelected = true;
break;
}
} catch (Exception e) {
LOG.warn("{} electNewDpnForSubnetRoute: Unable to find TepIp for rd {} subnetroute subnetip {}" + " for dpnid {}, attempt next", LOGGING_PREFIX, rd, subnetIp, nhDpnId.toString(), e);
continue;
}
}
}
if (!isAlternateDpnSelected) {
// If no alternate Dpn is selected as nextHopDpn, withdraw the subnetroute if it had a nextHop already.
if (isRouteAdvertised(subOpBuilder) && oldDpnId != null) {
LOG.info("{} electNewDpnForSubnetRoute: No alternate DPN available for subnet {} subnetIp {} vpn {}" + " rd {} Prefix withdrawn from BGP", LOGGING_PREFIX, subnetId.getValue(), subnetIp, vpnName, rd);
// Withdraw route from BGP for this subnet
boolean routeWithdrawn = deleteSubnetRouteFromFib(rd, subnetIp, vpnName, isBgpVpn);
subOpBuilder.setNhDpnId(null);
subOpBuilder.setLastAdvState(subOpBuilder.getRouteAdvState());
if (routeWithdrawn) {
subOpBuilder.setRouteAdvState(TaskState.Withdrawn);
} else {
LOG.error("{} electNewDpnForSubnetRoute: Withdrawing NextHopDPN {} for subnet {} subnetIp {}" + " vpn {} rd {} from BGP failed", LOGGING_PREFIX, oldDpnId, subnetId.getValue(), subnetIp, vpnName, rd);
subOpBuilder.setRouteAdvState(TaskState.PendingWithdraw);
}
}
} else {
// If alternate Dpn is selected as nextHopDpn, use that for subnetroute.
subOpBuilder.setNhDpnId(nhDpnId);
if (VpnUtil.isL3VpnOverVxLan(subOpBuilder.getL3vni())) {
l3vni = subOpBuilder.getL3vni();
} else {
label = getLabel(rd, subnetIp);
subOpBuilder.setLabel(label);
}
// update the VRF entry for the subnetroute.
isRouteAdvertised = addSubnetRouteToFib(rd, subnetIp, nhDpnId, nhTepIp, vpnName, elanTag, label, l3vni, subnetId, isBgpVpn, networkName);
subOpBuilder.setLastAdvState(subOpBuilder.getRouteAdvState());
if (isRouteAdvertised) {
subOpBuilder.setRouteAdvState(TaskState.Advertised);
} else {
LOG.error("{} electNewDpnForSubnetRoute: Swapping to add new NextHopDpn {} for subnet {} subnetIp {}" + " vpn {} rd {} failed", LOGGING_PREFIX, nhDpnId, subnetId.getValue(), subnetIp, vpnName, rd);
subOpBuilder.setRouteAdvState(TaskState.PendingAdvertise);
}
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.NextHop in project netvirt by opendaylight.
the class VpnSubnetRouteHandler method onInterfaceUp.
// TODO Clean up the exception handling
@SuppressWarnings("checkstyle:IllegalCatch")
public void onInterfaceUp(BigInteger dpnId, String intfName, Uuid subnetId) {
// TODO(vivek): Change this to use more granularized lock at subnetId level
SubnetToDpn subDpn = null;
if (dpnId == null || Objects.equals(dpnId, BigInteger.ZERO)) {
LOG.error("{} onInterfaceUp: Unable to determine the DPNID for port {} on subnet {}", LOGGING_PREFIX, intfName, subnetId.getValue());
return;
}
try {
VpnUtil.lockSubnet(lockManager, subnetId.getValue());
try {
InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier = InstanceIdentifier.builder(SubnetOpData.class).child(SubnetOpDataEntry.class, new SubnetOpDataEntryKey(subnetId)).build();
Optional<SubnetOpDataEntry> optionalSubs = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, subOpIdentifier);
if (!optionalSubs.isPresent()) {
LOG.trace("{} onInterfaceUp: SubnetOpDataEntry for subnet {} is not available." + " Ignoring interfaceUp for port{}", LOGGING_PREFIX, subnetId.getValue(), intfName);
return;
}
subOpDpnManager.addPortOpDataEntry(intfName, subnetId, dpnId);
subDpn = subOpDpnManager.addInterfaceToDpn(subnetId, dpnId, intfName);
if (subDpn == null) {
return;
}
SubnetOpDataEntry subnetOpDataEntry = optionalSubs.get();
SubnetOpDataEntryBuilder subOpBuilder = new SubnetOpDataEntryBuilder(subnetOpDataEntry);
LOG.info("{} onInterfaceUp: Updating the SubnetOpDataEntry node for subnet {} subnetIp {} vpn {}" + " rd {} TaskState {} lastTaskState {}", LOGGING_PREFIX, subnetId.getValue(), subOpBuilder.getSubnetCidr(), subOpBuilder.getVpnName(), subOpBuilder.getVrfId(), subOpBuilder.getRouteAdvState(), subOpBuilder.getLastAdvState());
boolean isExternalSubnetVpn = VpnUtil.isExternalSubnetVpn(subnetOpDataEntry.getVpnName(), subnetId.getValue());
List<SubnetToDpn> subDpnList = subOpBuilder.getSubnetToDpn();
subDpnList.add(subDpn);
subOpBuilder.setSubnetToDpn(subDpnList);
if (subOpBuilder.getRouteAdvState() != TaskState.Advertised) {
if (subOpBuilder.getNhDpnId() == null) {
// No nexthop selected yet, elect one now
electNewDpnForSubnetRoute(subOpBuilder, null, /* oldDpnId */
subnetId, null, /*networkId*/
!isExternalSubnetVpn);
} else if (!isExternalSubnetVpn) {
// Already nexthop has been selected, only publishing to bgp required, so publish to bgp
getNexthopTepAndPublishRoute(subOpBuilder, subnetId);
}
}
SubnetOpDataEntry subOpEntry = subOpBuilder.build();
MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, subOpIdentifier, subOpEntry);
LOG.info("{} onInterfaceUp: Updated subnetopdataentry to OP Datastore port {} up for subnet {}" + " subnetIp {} vpnName {} rd {} TaskState {} lastTaskState {} ", LOGGING_PREFIX, intfName, subnetId.getValue(), subOpEntry.getSubnetCidr(), subOpEntry.getVpnName(), subOpEntry.getVrfId(), subOpEntry.getRouteAdvState(), subOpEntry.getLastAdvState());
} catch (Exception ex) {
LOG.error("{} onInterfaceUp: Updation of SubnetOpDataEntry for subnet {} on port {} up failed", LOGGING_PREFIX, subnetId.getValue(), intfName, ex);
} finally {
VpnUtil.unlockSubnet(lockManager, subnetId.getValue());
}
} catch (RuntimeException e) {
LOG.error("{} onInterfaceUp: Unable to handle interface up event for port {} in subnet {}", LOGGING_PREFIX, intfName, subnetId.getValue(), e);
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.NextHop in project netvirt by opendaylight.
the class InterVpnLinkUtil method leakRoute.
/**
* Leaks a route from one VPN to another. By default, the origin for this leaked route is INTERVPN.
*
* @param broker dataBroker service reference
* @param bgpManager Used to advertise routes to the BGP Router
* @param interVpnLink Reference to the object that holds the info about the link between the 2 VPNs
* @param srcVpnUuid UUID of the VPN that has the route that is going to be leaked to the other VPN
* @param dstVpnUuid UUID of the VPN that is going to receive the route
* @param prefix Prefix of the route
* @param label Label of the route in the original VPN
*/
// TODO Clean up the exception handling
@SuppressWarnings("checkstyle:IllegalCatch")
public static void leakRoute(DataBroker broker, IBgpManager bgpManager, InterVpnLink interVpnLink, String srcVpnUuid, String dstVpnUuid, String prefix, Long label) {
Preconditions.checkNotNull(interVpnLink);
// The source VPN must participate in the InterVpnLink
Preconditions.checkArgument(interVpnLink.getFirstEndpoint().getVpnUuid().getValue().equals(srcVpnUuid) || interVpnLink.getSecondEndpoint().getVpnUuid().getValue().equals(srcVpnUuid), "The source VPN {} does not participate in the interVpnLink {}", srcVpnUuid, interVpnLink.getName());
// The destination VPN must participate in the InterVpnLink
Preconditions.checkArgument(interVpnLink.getFirstEndpoint().getVpnUuid().getValue().equals(dstVpnUuid) || interVpnLink.getSecondEndpoint().getVpnUuid().getValue().equals(dstVpnUuid), "The destination VPN {} does not participate in the interVpnLink {}", dstVpnUuid, interVpnLink.getName());
boolean destinationIs1stEndpoint = interVpnLink.getFirstEndpoint().getVpnUuid().getValue().equals(dstVpnUuid);
String endpointIp = destinationIs1stEndpoint ? interVpnLink.getSecondEndpoint().getIpAddress().getValue() : interVpnLink.getFirstEndpoint().getIpAddress().getValue();
VrfEntry newVrfEntry = FibHelper.getVrfEntryBuilder(prefix, label, endpointIp, RouteOrigin.INTERVPN, null).build();
String dstVpnRd = VpnUtil.getVpnRd(broker, dstVpnUuid);
InstanceIdentifier<VrfEntry> newVrfEntryIid = InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(dstVpnRd)).child(VrfEntry.class, new VrfEntryKey(newVrfEntry.getDestPrefix())).build();
VpnUtil.asyncWrite(broker, LogicalDatastoreType.CONFIGURATION, newVrfEntryIid, newVrfEntry);
// Finally, route is advertised it to the DC-GW. But while in the FibEntries the nexthop is the other
// endpoint's IP, in the DC-GW the nexthop for those prefixes are the IPs of those DPNs where the target
// VPN has been instantiated
Optional<InterVpnLinkState> optVpnLinkState = getInterVpnLinkState(broker, interVpnLink.getName());
if (optVpnLinkState.isPresent()) {
InterVpnLinkState vpnLinkState = optVpnLinkState.get();
List<BigInteger> dpnIdList = destinationIs1stEndpoint ? vpnLinkState.getFirstEndpointState().getDpId() : vpnLinkState.getSecondEndpointState().getDpId();
List<String> nexthops = new ArrayList<>();
for (BigInteger dpnId : dpnIdList) {
nexthops.add(InterfaceUtils.getEndpointIpAddressForDPN(broker, dpnId));
}
try {
LOG.debug("Advertising route in VPN={} [prefix={} label={} nexthops={}] to DC-GW", dstVpnRd, newVrfEntry.getDestPrefix(), label.intValue(), nexthops);
bgpManager.advertisePrefix(dstVpnRd, null, /*macAddress*/
newVrfEntry.getDestPrefix(), nexthops, VrfEntry.EncapType.Mplsgre, label.intValue(), 0, /*l3vni*/
0, /*l2vni*/
null);
} catch (Exception ex) {
LOG.error("Could not advertise prefix {} with label {} to VPN rd={}", newVrfEntry.getDestPrefix(), label.intValue(), dstVpnRd, ex);
}
} else {
LOG.warn("Error when advertising leaked routes: Could not find State for InterVpnLink={}", interVpnLink.getName());
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.NextHop in project netvirt by opendaylight.
the class L3vpnOverMplsGrePopulator method createOperationalAdjacency.
@Override
public Adjacency createOperationalAdjacency(L3vpnInput input) {
Adjacency nextHop = input.getNextHop();
String nextHopIp = input.getNextHopIp();
String prefix = VpnUtil.getIpPrefix(nextHop.getIpAddress());
List<String> adjNextHop = nextHop.getNextHopIpList();
String rd = input.getRd();
String primaryRd = input.getPrimaryRd();
String vpnName = input.getVpnName();
long label = VpnUtil.getUniqueId(idManager, VpnConstants.VPN_IDPOOL_NAME, VpnUtil.getNextHopLabelKey(primaryRd, prefix));
if (label == VpnConstants.INVALID_LABEL) {
String error = "Unable to fetch label from Id Manager. Bailing out of creation of operational " + "vpn interface adjacency " + prefix + "for vpn " + vpnName;
throw new NullPointerException(error);
}
List<String> nextHopList = adjNextHop != null && !adjNextHop.isEmpty() ? adjNextHop : nextHopIp == null ? Collections.emptyList() : Collections.singletonList(nextHopIp);
return new AdjacencyBuilder(nextHop).setLabel(label).setNextHopIpList(nextHopList).setIpAddress(prefix).setVrfId(rd).setKey(new AdjacencyKey(prefix)).setAdjacencyType(nextHop.getAdjacencyType()).setSubnetGatewayMacAddress(nextHop.getSubnetGatewayMacAddress()).build();
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.NextHop in project netvirt by opendaylight.
the class L3vpnPopulator method addToLabelMapper.
public void addToLabelMapper(Long label, BigInteger dpnId, String prefix, List<String> nextHopIpList, Long vpnId, String vpnInterfaceName, Long elanTag, boolean isSubnetRoute, String rd) {
Preconditions.checkNotNull(label, "addToLabelMapper: label cannot be null or empty!");
Preconditions.checkNotNull(prefix, "addToLabelMapper: prefix cannot be null or empty!");
Preconditions.checkNotNull(vpnId, "addToLabelMapper: vpnId cannot be null or empty!");
Preconditions.checkNotNull(rd, "addToLabelMapper: rd cannot be null or empty!");
if (!isSubnetRoute) {
// NextHop must be present for non-subnetroute entries
Preconditions.checkNotNull(nextHopIpList, "addToLabelMapper: nextHopIp cannot be null or empty!");
}
synchronized (label.toString().intern()) {
addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
LOG.info("addToLabelMapper: label {} dpn {} prefix {} nexthoplist {} vpnid {} vpnIntfcName {} rd {}" + " elanTag {}", label, dpnId, prefix, nextHopIpList, vpnId, vpnInterfaceName, rd, elanTag);
if (dpnId != null) {
LabelRouteInfoBuilder lriBuilder = new LabelRouteInfoBuilder();
lriBuilder.setLabel(label).setDpnId(dpnId).setPrefix(prefix).setNextHopIpList(nextHopIpList).setParentVpnid(vpnId).setIsSubnetRoute(isSubnetRoute);
if (elanTag != null) {
lriBuilder.setElanTag(elanTag);
} else {
LOG.warn("addToLabelMapper: elanTag is null for label {} prefix {} rd {} vpnId {}", label, prefix, rd, vpnId);
}
if (vpnInterfaceName != null) {
lriBuilder.setVpnInterfaceName(vpnInterfaceName);
} else {
LOG.warn("addToLabelMapper: vpn interface is null for label {} prefix {} rd {} vpnId {}", label, prefix, rd, vpnId);
}
lriBuilder.setParentVpnRd(rd);
VpnInstanceOpDataEntry vpnInstanceOpDataEntry = VpnUtil.getVpnInstanceOpData(broker, rd);
if (vpnInstanceOpDataEntry != null) {
List<String> vpnInstanceNames = Collections.singletonList(vpnInstanceOpDataEntry.getVpnInstanceName());
lriBuilder.setVpnInstanceList(vpnInstanceNames);
}
LabelRouteInfo lri = lriBuilder.build();
InstanceIdentifier<LabelRouteInfo> lriIid = InstanceIdentifier.builder(LabelRouteMap.class).child(LabelRouteInfo.class, new LabelRouteInfoKey(label)).build();
tx.merge(LogicalDatastoreType.OPERATIONAL, lriIid, lri, true);
LOG.info("addToLabelMapper: Added label route info to label {} prefix {} nextHopList {} vpnId {}" + " interface {} rd {} elantag {}", label, prefix, nextHopIpList, vpnId, vpnInterfaceName, rd, elanTag);
} else {
LOG.warn("addToLabelMapper: Can't add entry to label map for label {} prefix {} nextHopList {}" + " vpnId {} interface {} rd {} elantag {}, dpnId is null", label, prefix, nextHopIpList, vpnId, vpnInterfaceName, rd, elanTag);
}
}), LOG, "addToLabelMapper");
}
}
Aggregations