use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.l3vpn.lb.nexthops.Nexthops in project netvirt by opendaylight.
the class FibUtil method removeOrUpdateNextHopInfo.
public static void removeOrUpdateNextHopInfo(BigInteger dpnId, String nextHopKey, String groupId, Nexthops nexthops, WriteTransaction tx) {
InstanceIdentifier<Nexthops> nextHopsId = getNextHopsIdentifier(nextHopKey);
List<String> targetDeviceIds = nexthops.getTargetDeviceId();
targetDeviceIds.remove(dpnId.toString());
if (targetDeviceIds.isEmpty()) {
tx.delete(LogicalDatastoreType.OPERATIONAL, nextHopsId);
} else {
Nexthops nextHopsToGroupId = new NexthopsBuilder().setKey(new NexthopsKey(nextHopKey)).setNexthopKey(nextHopKey).setGroupId(groupId).setTargetDeviceId(targetDeviceIds).build();
tx.put(LogicalDatastoreType.OPERATIONAL, nextHopsId, nextHopsToGroupId);
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.l3vpn.lb.nexthops.Nexthops in project netvirt by opendaylight.
the class NexthopManager method getVpnNexthop.
protected VpnNexthop getVpnNexthop(long vpnId, String ipAddress) {
// check if vpn node is there
InstanceIdentifierBuilder<VpnNexthops> idBuilder = InstanceIdentifier.builder(L3nexthop.class).child(VpnNexthops.class, new VpnNexthopsKey(vpnId));
InstanceIdentifier<VpnNexthops> id = idBuilder.build();
Optional<VpnNexthops> vpnNexthops = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
if (vpnNexthops.isPresent()) {
// get nexthops list for vpn
List<VpnNexthop> nexthops = vpnNexthops.get().getVpnNexthop();
for (VpnNexthop nexthop : nexthops) {
if (nexthop.getIpAddress().equals(ipAddress)) {
// return nexthop
LOG.trace("VpnNextHop : {}", nexthop);
return nexthop;
}
}
// return null if not found
}
return null;
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.l3vpn.lb.nexthops.Nexthops in project netvirt by opendaylight.
the class NexthopManager method removeOrUpdateDcGwLoadBalancingGroup.
/**
* This method is invoked when the tunnel state is removed from DS.
* If the there is just one DC-GW left in configuration then the LB groups can be deleted.
* Otherwise, the groups are just updated.
*/
public void removeOrUpdateDcGwLoadBalancingGroup(List<String> availableDcGws, BigInteger dpnId, String destinationIp) {
Preconditions.checkNotNull(availableDcGws, "There are no dc-gws present");
WriteTransaction configTx = dataBroker.newWriteOnlyTransaction();
WriteTransaction operationalTx = dataBroker.newWriteOnlyTransaction();
int noOfDcGws = availableDcGws.size();
// If availableDcGws does not contain the destination Ip it means this is a configuration delete.
if (!availableDcGws.contains(destinationIp)) {
availableDcGws.add(destinationIp);
Collections.sort(availableDcGws);
}
// TODO : Place the logic to construct all possible DC-GW combination here.
int bucketId = availableDcGws.indexOf(destinationIp);
Optional<DpnLbNexthops> dpnLbNextHops = fibUtil.getDpnLbNexthops(dpnId, destinationIp);
if (!dpnLbNextHops.isPresent()) {
return;
}
List<String> nextHopKeys = dpnLbNextHops.get().getNexthopKey();
nextHopKeys.forEach(nextHopKey -> {
Optional<Nexthops> optionalNextHops = fibUtil.getNexthops(nextHopKey);
if (!optionalNextHops.isPresent()) {
return;
}
Nexthops nexthops = optionalNextHops.get();
final String groupId = nexthops.getGroupId();
final long groupIdValue = Long.parseLong(groupId);
if (noOfDcGws > 1) {
mdsalApiManager.removeBucketToTx(dpnId, groupIdValue, bucketId, configTx);
} else {
Group group = MDSALUtil.buildGroup(groupIdValue, nextHopKey, GroupTypes.GroupSelect, MDSALUtil.buildBucketLists(Collections.emptyList()));
LOG.trace("Removed LB group {} on dpn {}", group, dpnId);
mdsalApiManager.removeGroupToTx(dpnId, group, configTx);
removeNextHopPointer(nextHopKey);
}
// When the DC-GW is removed from configuration.
if (noOfDcGws != availableDcGws.size()) {
FibUtil.removeOrUpdateNextHopInfo(dpnId, nextHopKey, groupId, nexthops, operationalTx);
}
});
FibUtil.removeDpnIdToNextHopInfo(destinationIp, dpnId, operationalTx);
configTx.submit();
operationalTx.submit();
return;
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.l3vpn.lb.nexthops.Nexthops in project netvirt by opendaylight.
the class NeutronvpnManager method checkAlarmExtraRoutes.
/**
* This method setup or down an alarm about extra route fault.
* When extra routes are configured, through a router, if the number of nexthops is greater than the number of
* available RDs, then an alarm and an error is generated.<br>
* <b>Be careful</b> the routeList could be changed.
*
* @param vpnId the vpnId of vpn to control.
* @param routeList the list of router to check, it could be modified.
*/
private void checkAlarmExtraRoutes(Uuid vpnId, List<Routes> routeList) {
if (!neutronvpnAlarm.isAlarmEnabled()) {
LOG.debug("checkAlarmExtraRoutes is not enable for vpnId {} routeList {}", vpnId, routeList);
return;
}
VpnInstance vpnInstance = neutronvpnUtils.getVpnInstance(dataBroker, vpnId);
if (vpnInstance == null || routeList == null || routeList.isEmpty() || !neutronvpnAlarm.isAlarmEnabled()) {
LOG.debug("checkAlarmExtraRoutes have args null as following : vpnId {} routeList {}", vpnId, routeList);
return;
}
List<Routes> routesError = new ArrayList();
for (Routes route : routeList) {
// count the number of nexthops for each same route.getDestingation().getValue()
String destination = String.valueOf(route.getDestination().getValue());
String nextHop = String.valueOf(route.getNexthop().getValue());
List<String> nextHopList = new ArrayList();
nextHopList.add(nextHop);
int nbNextHops = 0;
for (Routes routeTmp : routeList) {
String routeDest = String.valueOf(routeTmp.getDestination().getValue());
if (!destination.equals(routeDest)) {
continue;
}
String routeNextH = String.valueOf(routeTmp.getNexthop().getValue());
if (nextHop.equals(routeNextH)) {
continue;
}
nbNextHops++;
nextHopList.add(new String(routeTmp.getNexthop().getValue()));
}
final List<String> rdList = new ArrayList();
if (vpnInstance.getIpv4Family() != null && vpnInstance.getIpv4Family().getRouteDistinguisher() != null) {
vpnInstance.getIpv4Family().getRouteDistinguisher().stream().forEach(rd -> {
if (rd != null) {
rdList.add(rd);
}
});
}
if (vpnInstance.getIpv6Family() != null && vpnInstance.getIpv6Family().getRouteDistinguisher() != null) {
vpnInstance.getIpv6Family().getRouteDistinguisher().stream().forEach(rd -> {
if (rd != null && !rdList.contains(rd)) {
rdList.add(rd);
}
});
}
// 1. VPN Instance Name
String typeAlarm = "for vpnId: " + vpnId + " have exceeded next hops for prefixe";
// 2. Router ID
Uuid routerUuid = neutronvpnUtils.getRouterforVpn(vpnId);
StringBuilder detailsAlarm = new StringBuilder("routerUuid: ");
detailsAlarm.append(routerUuid == null ? vpnId.toString() : routerUuid.getValue());
// 3. List of RDs associated with the VPN
detailsAlarm.append(" List of RDs associated with the VPN: ");
for (String s : rdList) {
detailsAlarm.append(s);
detailsAlarm.append(", ");
}
// 4. Prefix in question
detailsAlarm.append(" for prefix: ");
detailsAlarm.append(route.getDestination().getValue());
// 5. List of NHs for the prefix
detailsAlarm.append(" for nextHops: ");
for (String s : nextHopList) {
detailsAlarm.append(s);
detailsAlarm.append(", ");
}
if (rdList.size() < nbNextHops) {
neutronvpnAlarm.raiseNeutronvpnAlarm(typeAlarm, detailsAlarm.toString());
LOG.error("there are too many next hops for prefixe in vpn {}", vpnId);
routesError.add(route);
} else {
neutronvpnAlarm.clearNeutronvpnAlarm(typeAlarm, detailsAlarm.toString());
}
}
// in routesError there are a few route raised in alarm, so they have not to be used
routeList.removeAll(routesError);
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.l3vpn.lb.nexthops.Nexthops in project netvirt by opendaylight.
the class VpnInterfaceManager method processVpnInterfaceAdjacencies.
@SuppressWarnings("checkstyle:IllegalCatch")
protected void processVpnInterfaceAdjacencies(BigInteger dpnId, final int lportTag, String vpnName, String primaryRd, String interfaceName, final long vpnId, WriteTransaction writeConfigTxn, WriteTransaction writeOperTxn, final WriteTransaction writeInvTxn, Interface interfaceState) {
InstanceIdentifier<VpnInterface> identifier = VpnUtil.getVpnInterfaceIdentifier(interfaceName);
// Read NextHops
InstanceIdentifier<Adjacencies> path = identifier.augmentation(Adjacencies.class);
Optional<Adjacencies> adjacencies = VpnUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, path);
if (!adjacencies.isPresent()) {
addVpnInterfaceToOperational(vpnName, interfaceName, dpnId, null, /*adjacencies*/
lportTag, null, /*gwMac*/
writeOperTxn);
return;
}
// Get the rd of the vpn instance
String nextHopIp = null;
try {
nextHopIp = InterfaceUtils.getEndpointIpAddressForDPN(dataBroker, dpnId);
} catch (Exception e) {
LOG.error("processVpnInterfaceAdjacencies: Unable to retrieve endpoint ip address for " + "dpnId {} for vpnInterface {} vpnName {}", dpnId, interfaceName, vpnName);
}
List<String> nhList = new ArrayList<>();
if (nextHopIp != null) {
nhList.add(nextHopIp);
LOG.debug("processVpnInterfaceAdjacencies: NextHop for interface {} on dpn {} in vpn {} is {}", interfaceName, dpnId, vpnName, nhList);
}
Optional<String> gwMac = Optional.absent();
String vpnInterfaceSubnetGwMacAddress = null;
VpnInstanceOpDataEntry vpnInstanceOpData = VpnUtil.getVpnInstanceOpData(dataBroker, primaryRd);
Long l3vni = vpnInstanceOpData.getL3vni();
boolean isL3VpnOverVxLan = VpnUtil.isL3VpnOverVxLan(l3vni);
VrfEntry.EncapType encapType = isL3VpnOverVxLan ? VrfEntry.EncapType.Vxlan : VrfEntry.EncapType.Mplsgre;
VpnPopulator registeredPopulator = L3vpnRegistry.getRegisteredPopulator(encapType);
List<Adjacency> nextHops = adjacencies.get().getAdjacency();
List<Adjacency> value = new ArrayList<>();
for (Adjacency nextHop : nextHops) {
String rd = primaryRd;
String nexthopIpValue = nextHop.getIpAddress().split("/")[0];
if (vpnInstanceOpData.getBgpvpnType() == VpnInstanceOpDataEntry.BgpvpnType.BGPVPNInternet && NWUtil.isIpv4Address(nexthopIpValue)) {
String prefix = nextHop.getIpAddress() == null ? "null" : VpnUtil.getIpPrefix(nextHop.getIpAddress());
LOG.debug("processVpnInterfaceAdjacencies: UnsupportedOperation : Not Adding prefix {} to interface {}" + " as InternetVpn has an IPV4 address {}", prefix, interfaceName, vpnName);
continue;
}
if (nextHop.getAdjacencyType() == AdjacencyType.PrimaryAdjacency) {
String prefix = VpnUtil.getIpPrefix(nextHop.getIpAddress());
Prefixes.PrefixCue prefixCue = nextHop.isPhysNetworkFunc() ? Prefixes.PrefixCue.PhysNetFunc : Prefixes.PrefixCue.None;
LOG.debug("processVpnInterfaceAdjacencies: Adding prefix {} to interface {} with nextHops {} on dpn {}" + " for vpn {}", prefix, interfaceName, nhList, dpnId, vpnName);
writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL, VpnUtil.getPrefixToInterfaceIdentifier(VpnUtil.getVpnId(dataBroker, vpnName), prefix), VpnUtil.getPrefixToInterface(dpnId, interfaceName, prefix, nextHop.getSubnetId(), prefixCue), true);
final Uuid subnetId = nextHop.getSubnetId();
String gatewayIp = nextHop.getSubnetGatewayIp();
if (gatewayIp == null) {
Optional<String> gatewayIpOptional = VpnUtil.getVpnSubnetGatewayIp(dataBroker, subnetId);
if (gatewayIpOptional.isPresent()) {
gatewayIp = gatewayIpOptional.get();
}
}
if (gatewayIp != null) {
gwMac = getMacAddressForSubnetIp(vpnName, interfaceName, gatewayIp);
if (gwMac.isPresent()) {
// A valid mac-address is available for this subnet-gateway-ip
// Use this for programming ARP_RESPONDER table here. And save this
// info into vpnInterface operational, so it can used in VrfEntryProcessor
// to populate L3_GW_MAC_TABLE there.
arpResponderHandler.addArpResponderFlow(dpnId, lportTag, interfaceName, gatewayIp, gwMac.get());
vpnInterfaceSubnetGwMacAddress = gwMac.get();
} else {
// A valid mac-address is not available for this subnet-gateway-ip
// Use the connected-mac-address to configure ARP_RESPONDER Table.
// Save this connected-mac-address as gateway-mac-address for the
// VrfEntryProcessor to use this later to populate the L3_GW_MAC_TABLE.
gwMac = InterfaceUtils.getMacAddressFromInterfaceState(interfaceState);
if (gwMac.isPresent()) {
VpnUtil.setupGwMacIfExternalVpn(dataBroker, mdsalManager, dpnId, interfaceName, vpnId, writeInvTxn, NwConstants.ADD_FLOW, gwMac.get());
arpResponderHandler.addArpResponderFlow(dpnId, lportTag, interfaceName, gatewayIp, gwMac.get());
} else {
LOG.error("processVpnInterfaceAdjacencies: Gateway MAC for subnet ID {} could not be " + "obtained, cannot create ARP responder flow for interface name {}, vpnName {}, " + "gwIp {}", subnetId, interfaceName, vpnName, gatewayIp);
}
}
} else {
LOG.warn("processVpnInterfaceAdjacencies: Gateway IP for subnet ID {} could not be obtained, " + "cannot create ARP responder flow for interface name {}, vpnName {}", subnetId, interfaceName, vpnName);
gwMac = InterfaceUtils.getMacAddressFromInterfaceState(interfaceState);
}
LOG.info("processVpnInterfaceAdjacencies: Added prefix {} to interface {} with nextHops {} on dpn {}" + " for vpn {}", prefix, interfaceName, nhList, dpnId, vpnName);
} else {
// Extra route adjacency
String prefix = VpnUtil.getIpPrefix(nextHop.getIpAddress());
String vpnPrefixKey = VpnUtil.getVpnNamePrefixKey(vpnName, prefix);
synchronized (vpnPrefixKey.intern()) {
java.util.Optional<String> rdToAllocate = VpnUtil.allocateRdForExtraRouteAndUpdateUsedRdsMap(dataBroker, vpnId, null, prefix, vpnName, nextHop.getNextHopIpList().get(0), dpnId);
if (rdToAllocate.isPresent()) {
rd = rdToAllocate.get();
LOG.info("processVpnInterfaceAdjacencies: The rd {} is allocated for the extraroute {}", rd, prefix);
} else {
LOG.error("processVpnInterfaceAdjacencies: No rds to allocate extraroute {}", prefix);
continue;
}
}
LOG.info("processVpnInterfaceAdjacencies: Added prefix {} and nextHopList {} as extra-route for vpn{}" + " interface {} on dpn {}", nextHop.getIpAddress(), nextHop.getNextHopIpList(), vpnName, interfaceName, dpnId);
}
// Please note that primary adjacency will use a subnet-gateway-mac-address that
// can be different from the gateway-mac-address within the VRFEntry as the
// gateway-mac-address is a superset.
RouteOrigin origin = nextHop.getAdjacencyType() == AdjacencyType.PrimaryAdjacency ? RouteOrigin.LOCAL : RouteOrigin.STATIC;
L3vpnInput input = new L3vpnInput().setNextHop(nextHop).setRd(rd).setVpnName(vpnName).setInterfaceName(interfaceName).setNextHopIp(nextHopIp).setPrimaryRd(primaryRd).setSubnetGatewayMacAddress(vpnInterfaceSubnetGwMacAddress).setRouteOrigin(origin);
Adjacency operationalAdjacency = null;
try {
operationalAdjacency = registeredPopulator.createOperationalAdjacency(input);
} catch (NullPointerException e) {
LOG.error("processVpnInterfaceAdjacencies: failed to create operational adjacency: input: {}, {}", input, e.getMessage());
return;
}
if (nextHop.getAdjacencyType() != AdjacencyType.PrimaryAdjacency) {
vpnManager.addExtraRoute(vpnName, nextHop.getIpAddress(), nextHop.getNextHopIpList().get(0), rd, vpnName, l3vni, origin, interfaceName, operationalAdjacency, encapType, writeConfigTxn);
}
value.add(operationalAdjacency);
}
AdjacenciesOp aug = VpnUtil.getVpnInterfaceOpDataEntryAugmentation(value);
addVpnInterfaceToOperational(vpnName, interfaceName, dpnId, aug, lportTag, gwMac.isPresent() ? gwMac.get() : null, writeOperTxn);
L3vpnInput input = new L3vpnInput().setNextHopIp(nextHopIp).setL3vni(l3vni).setPrimaryRd(primaryRd).setGatewayMac(gwMac.orNull()).setInterfaceName(interfaceName).setVpnName(vpnName).setDpnId(dpnId).setEncapType(encapType);
for (Adjacency nextHop : aug.getAdjacency()) {
// Adjacencies other than primary Adjacencies are handled in the addExtraRoute call above.
if (nextHop.getAdjacencyType() == AdjacencyType.PrimaryAdjacency) {
RouteOrigin origin = nextHop.getAdjacencyType() == AdjacencyType.PrimaryAdjacency ? RouteOrigin.LOCAL : RouteOrigin.STATIC;
input.setNextHop(nextHop).setRd(nextHop.getVrfId()).setRouteOrigin(origin);
registeredPopulator.populateFib(input, writeConfigTxn);
}
}
}
Aggregations