});
}
- Optional<String> vpnUuid = FibUtil.getVpnNameFromRd(dataBroker, rd);
- if ( vpnUuid.isPresent() ) {
- Optional<InterVpnLink> interVpnLink = FibUtil.getInterVpnLinkByVpnUuid(dataBroker, vpnUuid.get());
+ Optional<String> optVpnUuid = FibUtil.getVpnNameFromRd(dataBroker, rd);
+ if ( optVpnUuid.isPresent() ) {
+ Optional<InterVpnLink> interVpnLink = FibUtil.getInterVpnLinkByVpnUuid(dataBroker, optVpnUuid.get());
if ( interVpnLink.isPresent() ) {
+ String vpnUuid = optVpnUuid.get();
String routeNexthop = vrfEntry.getNextHopAddressList().get(0);
- if ( isNexthopTheOtherVpnLinkEndpoint(routeNexthop, vpnUuid.get(), interVpnLink.get()) ) {
+ if ( isNexthopTheOtherVpnLinkEndpoint(routeNexthop, vpnUuid, interVpnLink.get()) ) {
// This is an static route that points to the other endpoint of an InterVpnLink
// In that case, we should add another entry in FIB table pointing to LPortDispatcher table.
- installRouteInInterVpnLink(interVpnLink.get(), rd, vrfEntry, vpnId);
+ installRouteInInterVpnLink(interVpnLink.get(), vpnUuid, vrfEntry, vpnId);
}
}
}
Preconditions.checkNotNull(interVpnLink, "InterVpnLink cannot be null");
Preconditions.checkArgument(vrfEntry.getNextHopAddressList() != null
&& vrfEntry.getNextHopAddressList().size() == 1);
+ String destination = vrfEntry.getDestPrefix();
+ String nextHop = vrfEntry.getNextHopAddressList().get(0);
// After having received a static route, we should check if the vpn is part of an inter-vpn-link.
// In that case, we should populate the FIB table of the VPN pointing to LPortDisptacher table
}
if ( ! interVpnLinkState.get().getState().equals(InterVpnLinkState.State.Active) ) {
LOG.warn("Route to {} with nexthop={} cannot be installed because the interVpnLink {} is not active",
- vrfEntry.getDestPrefix(), vrfEntry.getNextHopAddressList().get(0), interVpnLink.getName());
+ destination, nextHop, interVpnLink.getName());
return;
}
ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME, NwConstants.L3VPN_SERVICE_INDEX)),
MetaDataUtil.getMetaDataMaskForLPortDispatcher()
};
+ int instIdx = 0;
List<Instruction> instructions =
Arrays.asList(new InstructionInfo(InstructionType.write_metadata, metadata).buildInstruction(0),
new InstructionInfo(InstructionType.goto_table,
new long[] { NwConstants.L3_INTERFACE_TABLE }).buildInstruction(1));
- String values[] = vrfEntry.getDestPrefix().split("/");
+ String values[] = destination.split("/");
String destPrefixIpAddress = values[0];
int prefixLength = (values.length == 1) ? 0 : Integer.parseInt(values[1]);
}
int priority = DEFAULT_FIB_FLOW_PRIORITY + prefixLength;
- String nextHop = vrfEntry.getNextHopAddressList().get(0);
- String flowRef = getInterVpnFibFlowRef(interVpnLink.getName(), vrfEntry.getDestPrefix(), nextHop);
+ String flowRef = getInterVpnFibFlowRef(interVpnLink.getName(), destination, nextHop);
Flow flowEntity = MDSALUtil.buildFlowNew(NwConstants.L3_FIB_TABLE, flowRef, priority, flowRef, 0, 0,
COOKIE_VM_FIB_TABLE, matches, instructions);
sn = optSn.get();
oldVpnId = sn.getVpnId();
List<String> ips = sn.getRouterInterfaceFixedIps();
- if ( ips != null ) {
- for (String ipValue : ips) {
- IpAddress ip = new IpAddress(ipValue.toCharArray());
- if (oldVpnId != null) {
- InstanceIdentifier<VpnPortipToPort> id = NeutronvpnUtils.buildVpnPortipToPortIdentifier(oldVpnId.getValue(), ipValue);
- Optional<VpnPortipToPort> optionalVpnPort = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
- if (optionalVpnPort.isPresent()) {
- removeVpnPortFixedIpToPort(oldVpnId.getValue(), ipValue);
- }
+ for (String ipValue : ips) {
+ IpAddress ip = new IpAddress(ipValue.toCharArray());
+ if (oldVpnId != null) {
+ InstanceIdentifier<VpnPortipToPort> id = NeutronvpnUtils.buildVpnPortipToPortIdentifier(oldVpnId.getValue(), ipValue);
+ Optional<VpnPortipToPort> optionalVpnPort = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
+ if (optionalVpnPort.isPresent()) {
+ removeVpnPortFixedIpToPort(oldVpnId.getValue(), ipValue);
}
- createVpnPortFixedIpToPort(vpnId.getValue(), ipValue, sn.getRouterInterfaceName().getValue(),
- sn.getRouterIntfMacAddress(), true, true, false);
}
- } else {
- LOG.warn("No fixed IPs configured for router interface. VpnId={} subnetId={}", vpnId, subnet);
+ createVpnPortFixedIpToPort(vpnId.getValue(), ipValue, sn.getRouterInterfaceName().getValue(),
+ sn.getRouterIntfMacAddress(), true, true, false);
}
}
import org.opendaylight.netvirt.fibmanager.api.IFibManager;
+import java.math.BigInteger;
+import java.util.List;
+
public interface IVpnManager {
void setFibManager(IFibManager fibManager);
void addExtraRoute(String destination, String nextHop, String rd, String routerID, int label);
boolean isVPNConfigured();
long getArpCacheTimeoutMillis();
+ /**
+ * Retrieves the list of DPNs where the specified VPN has footprint
+ *
+ * @param vpnInstanceName The name of the Vpn instance
+ * @return The list of DPNs
+ */
+ List<BigInteger> getDpnsOnVpn(String vpnInstanceName);
}
public static final long MAX_WAIT_TIME_IN_MILLISECONDS = 90000;
public static final long PER_INTERFACE_MAX_WAIT_TIME_IN_MILLISECONDS = 10000;
public static final int ELAN_GID_MIN = 200000;
+
+ // An IdPool for Pseudo LPort tags, that is, lportTags that are no related to an interface.
+ // These lportTags must be higher than 65535 to avoid collision with interface LportTags
+ // TODO: This pool details and creation... should it be located in InterfaceManager?
+ public static final String PSEUDO_LPORT_TAG_ID_POOL_NAME = System.getProperty("lporttag.idpool.name", "lporttag");
+ public static final long LOWER_PSEUDO_LPORT_TAG = Long.getLong("lporttag.range.lower", 170001);
+ // The max value for LPortTag is 1F FF FF => 2097151
+ public static final long UPPER_PSEUDO_LPORT_TAG = Long.getLong("lporttag.range.upper", 2097151);
+
public static byte[] EthernetDestination_Broadcast = new byte[] { (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
(byte) 0xFF, (byte) 0xFF, (byte) 0xFF };
public static byte[] MAC_Broadcast = new byte[] { (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 };
package org.opendaylight.netvirt.vpnmanager;
import java.math.BigInteger;
+import java.util.Collection;
+import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
+import org.opendaylight.yangtools.yang.common.RpcError;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
} catch (InterruptedException | ExecutionException e) {
LOG.error("Failed to create idPool for VPN Service",e);
}
+
+ // Now an IdPool for InterVpnLink endpoint's pseudo ports
+ CreateIdPoolInput createPseudoLporTagPool =
+ new CreateIdPoolInputBuilder().setPoolName(VpnConstants.PSEUDO_LPORT_TAG_ID_POOL_NAME)
+ .setLow(VpnConstants.LOWER_PSEUDO_LPORT_TAG)
+ .setHigh(VpnConstants.UPPER_PSEUDO_LPORT_TAG)
+ .build();
+ try {
+ Future<RpcResult<Void>> result = idManager.createIdPool(createPseudoLporTagPool);
+ if (result != null && result.get().isSuccessful()) {
+ LOG.debug("Created IdPool for Pseudo Port tags");
+ } else {
+ Collection<RpcError> errors = result.get().getErrors();
+ StringBuilder errMsg = new StringBuilder();
+ for ( RpcError err : errors ) {
+ errMsg.append(err.getMessage()).append("\n");
+ }
+ LOG.error("IdPool creation for PseudoPort tags failed. Reasons: {}", errMsg);
+ }
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Failed to create idPool for Pseudo Port tags",e);
+ }
}
@Override
return vpnInstanceListener.isVPNConfigured();
}
+ @Override
+ public List<BigInteger> getDpnsOnVpn(String vpnInstanceName) {
+ return VpnUtil.getDpnsOnVpn(dataBroker, vpnInstanceName);
+ }
+
@Override
public boolean existsVpn(String vpnName) {
return VpnUtil.getVpnInstance(dataBroker, vpnName) != null;
}
return null;
}
+
+ public static List<BigInteger> getDpnsOnVpn(DataBroker dataBroker, String vpnInstanceName) {
+ List<BigInteger> result = new ArrayList<BigInteger>();
+ String rd = getVpnRd(dataBroker, vpnInstanceName);
+ if ( rd == null ) {
+ LOG.debug("Could not find Route-Distinguisher for VpnName={}", vpnInstanceName);
+ return result;
+ }
+
+ VpnInstanceOpDataEntry vpnInstanceOpData = getVpnInstanceOpData(dataBroker, rd);
+ if ( vpnInstanceOpData == null ) {
+ LOG.debug("Could not find OpState for VpnName={}", vpnInstanceName);
+ return result;
+ }
+
+ List<VpnToDpnList> vpnToDpnList = vpnInstanceOpData.getVpnToDpnList();
+ if ( vpnToDpnList == null ) {
+ LOG.debug("Could not find DPN footprint for VpnName={}", vpnInstanceName);
+ return result;
+ }
+ for ( VpnToDpnList vpnToDpn : vpnToDpnList) {
+ result.add(vpnToDpn.getDpnId());
+ }
+ return result;
+ }
static String getAssociatedExternalNetwork(DataBroker dataBroker, String routerId) {
InstanceIdentifier<Routers> id = buildRouterIdentifier(routerId);
new SecondEndpointStateBuilder().setVpnUuid(secondEndpointVpnUuid).setDpId(secondDpnList)
.setLportTag(secondVpnLportTag).build();
- InterVpnLinkUtil.updateInterVpnLinkState(dataBroker, add.getName(), InterVpnLinkState.State.Active, firstEndPointState,
- secondEndPointState);
+ InterVpnLinkUtil.updateInterVpnLinkState(dataBroker, add.getName(), InterVpnLinkState.State.Active,
+ firstEndPointState, secondEndPointState);
// Note that in the DPN of the firstEndpoint we install the lportTag of the secondEndpoint and viceversa
InterVpnLinkUtil.installLPortDispatcherTableFlow(dataBroker, mdsalManager, add, firstDpnList,
- secondEndpointVpnUuid, secondVpnLportTag);
+ secondEndpointVpnUuid, secondVpnLportTag);
InterVpnLinkUtil.installLPortDispatcherTableFlow(dataBroker, mdsalManager, add, secondDpnList,
- firstEndpointVpnUuid, firstVpnLportTag);
+ firstEndpointVpnUuid, firstVpnLportTag);
// Update the VPN -> DPNs Map.
// Note: when a set of DPNs is calculated for Vpn1, these DPNs are added to the VpnToDpn map of Vpn2. Why?
// because we do the handover from Vpn1 to Vpn2 in those DPNs, so in those DPNs we must know how to reach
SecondEndpointState secondEndPointState =
new SecondEndpointStateBuilder().setVpnUuid(secondEndpointVpnUuid)
.setLportTag(secondVpnLportTag).build();
- InterVpnLinkUtil.updateInterVpnLinkState(dataBroker, add.getName(), InterVpnLinkState.State.Error, firstEndPointState,
- secondEndPointState);
+ InterVpnLinkUtil.updateInterVpnLinkState(dataBroker, add.getName(), InterVpnLinkState.State.Error,
+ firstEndPointState, secondEndPointState);
}
}
private void releaseVpnLinkLPortTag(String idKey) {
- ReleaseIdInput releaseIdInput = new ReleaseIdInputBuilder().setPoolName(IfmConstants.IFM_IDPOOL_NAME)
- .setIdKey(idKey).build();
+ ReleaseIdInput releaseIdInput =
+ new ReleaseIdInputBuilder().setPoolName(VpnConstants.PSEUDO_LPORT_TAG_ID_POOL_NAME).setIdKey(idKey).build();
idManager.releaseId(releaseIdInput);
}
private Integer allocateVpnLinkLportTag(String idKey) {
AllocateIdInput getIdInput =
- new AllocateIdInputBuilder().setPoolName(IfmConstants.IFM_IDPOOL_NAME).setIdKey(idKey).build();
+ new AllocateIdInputBuilder().setPoolName(VpnConstants.PSEUDO_LPORT_TAG_ID_POOL_NAME)
+ .setIdKey(idKey)
+ .build();
try {
Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
RpcResult<AllocateIdOutput> rpcResult = result.get();
- if(rpcResult.isSuccessful()) {
+ if (rpcResult.isSuccessful()) {
return rpcResult.getResult().getIdValue().intValue();
} else {
LOG.warn("RPC Call to Get Unique Id returned with Errors {}", rpcResult.getErrors());
String errorMsg) {
// Setting InterVPNLink in error state in MDSAL
InterVpnLinkState vpnLinkErrorState =
- new InterVpnLinkStateBuilder(vpnLinkState).setState(InterVpnLinkState.State.Error)
- .setErrorDescription(errorMsg)
- .build();
+ new InterVpnLinkStateBuilder(vpnLinkState).setState(InterVpnLinkState.State.Error)
+ .setErrorDescription(errorMsg)
+ .build();
WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
tx.put(LogicalDatastoreType.CONFIGURATION, vpnLinkStateIid, vpnLinkErrorState, true);
tx.submit();