*/
package org.opendaylight.netvirt.vpnmanager.intervpnlink;
-
+import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
+import java.math.BigInteger;
+import java.util.ArrayList;
+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.controller.md.sal.binding.api.DataChangeListener;
import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
import org.opendaylight.genius.mdsalutil.NwConstants;
import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
-import org.opendaylight.netvirt.bgpmanager.api.RouteOrigin;
+import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
import org.opendaylight.netvirt.vpnmanager.VpnConstants;
import org.opendaylight.netvirt.vpnmanager.VpnUtil;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.InterVpnLinkCreationError;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.InterVpnLinkCreationErrorBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-
-public class InterVpnLinkListener extends AbstractDataChangeListener<InterVpnLink> {
- private static final Logger logger = LoggerFactory.getLogger(InterVpnLinkListener.class);
- private static final String NBR_OF_DPNS_PROPERTY_NAME = "vpnservice.intervpnlink.number.dpns";
- private static final int INVALID_ID = 0;
-
- private IMdsalApiManager mdsalManager;
- private IdManagerService idManager;
- private IBgpManager bgpManager;
- private NotificationPublishService notificationsService;
-
+public class InterVpnLinkListener extends AbstractDataChangeListener<InterVpnLink> implements AutoCloseable {
+ private static final Logger LOG = LoggerFactory.getLogger(InterVpnLinkListener.class);
private ListenerRegistration<DataChangeListener> listenerRegistration;
- private final DataBroker broker;
-
+ private final DataBroker dataBroker;
+ private final IMdsalApiManager mdsalManager;
+ private final IdManagerService idManager;
+ private final IBgpManager bgpManager;
+ private final NotificationPublishService notificationsService;
+ private static final String NBR_OF_DPNS_PROPERTY_NAME = "vpnservice.intervpnlink.number.dpns";
+ private static final long INVALID_ID = 0;
- public InterVpnLinkListener(DataBroker db, IdManagerService idManager, IMdsalApiManager mdsalManager,
- IBgpManager bgpManager, NotificationPublishService notifService) {
+ public InterVpnLinkListener(final DataBroker dataBroker, final IdManagerService idManager,
+ final IMdsalApiManager mdsalManager, final IBgpManager bgpManager,
+ final NotificationPublishService notifService) {
super(InterVpnLink.class);
- this.broker = db;
+ this.dataBroker = dataBroker;
this.idManager = idManager;
this.mdsalManager = mdsalManager;
this.bgpManager = bgpManager;
this.notificationsService = notifService;
- this.registerListener(db);
}
- public void close() {
- if (listenerRegistration != null) {
- try {
- listenerRegistration.close();
- } catch (final Exception e) {
- logger.error("Error when cleaning up DataChangeListener.", e);
- }
- listenerRegistration = null;
- }
- }
-
-
- /**
- * Register the databroker to all the possible changes from MDSAL - InterVpnLink class
- *
- * @param db dataBroker service reference
- */
- private void registerListener(DataBroker db) {
- try {
- this.listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
- this.getWildCardPath(),
- this,
- AsyncDataBroker.DataChangeScope.SUBTREE);
- } catch (Exception e) {
- logger.error("InterVpnLinkListener: DataChange listener registration fail!", e);
- throw new IllegalStateException("InterVpnLinkListener: registration Listener failed.", e);
- }
+ public void start() {
+ LOG.info("{} start", getClass().getSimpleName());
+ listenerRegistration = dataBroker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
+ getWildCardPath(), this, AsyncDataBroker.DataChangeScope.SUBTREE);
}
private InstanceIdentifier<InterVpnLink> getWildCardPath() {
return InstanceIdentifier.create(InterVpnLinks.class).child(InterVpnLink.class);
}
+ @Override
+ public void close() throws Exception {
+ if (listenerRegistration != null) {
+ listenerRegistration.close();
+ listenerRegistration = null;
+ }
+ LOG.info("{} close", getClass().getSimpleName());
+ }
+
private String getInterVpnLinkIfaceName(String vpnUuid, BigInteger dpnId ) {
return String.format("InterVpnLink.%s.%s", vpnUuid, dpnId.toString());
}
@Override
protected void add(InstanceIdentifier<InterVpnLink> identifier, InterVpnLink add) {
+ LOG.debug("Reacting to IVpnLink {} creation. Vpn1=[name={} EndpointIp={}] Vpn2=[name={} endpointIP={}]",
+ add.getName(), add.getFirstEndpoint().getVpnUuid(), add.getFirstEndpoint().getIpAddress(),
+ add.getSecondEndpoint().getVpnUuid(), add.getSecondEndpoint().getIpAddress());
+
int numberOfDpns = Integer.getInteger(NBR_OF_DPNS_PROPERTY_NAME, 1);
// Create VpnLink state
- InstanceIdentifier<InterVpnLinkState> vpnLinkStateIid = VpnUtil.getInterVpnLinkStateIid(add.getName());
+ InstanceIdentifier<InterVpnLinkState> vpnLinkStateIid = InterVpnLinkUtil.getInterVpnLinkStateIid(add.getName());
InterVpnLinkState vpnLinkState = new InterVpnLinkStateBuilder().setInterVpnLinkName(add.getName()).build();
- MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, vpnLinkStateIid, vpnLinkState);
+ MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnLinkStateIid, vpnLinkState);
InterVpnLinkKey key = add.getKey();
Uuid firstEndpointVpnUuid = add.getFirstEndpoint().getVpnUuid();
Uuid secondEndpointVpnUuid = add.getSecondEndpoint().getVpnUuid();
// First VPN
+ if ( VpnUtil.getVpnInstance(this.dataBroker, firstEndpointVpnUuid.getValue()) == null ) {
+ String errMsg = "InterVpnLink " + add.getName() + " creation error: could not find 1st endpoint Vpn "
+ + firstEndpointVpnUuid.getValue();
+ setInError(vpnLinkStateIid, vpnLinkState, errMsg);
+ return;
+ }
if (!checkVpnAvailability(key, firstEndpointVpnUuid)) {
- String errMsg = String.format("Vpn already associated with a previous inter-vpn-link {}",
- firstEndpointVpnUuid);
- logger.error(errMsg);
+ String errMsg = "InterVpnLink " + add.getName() + " creation error: Vpn " + firstEndpointVpnUuid.getValue()
+ + " is already associated to an inter-vpn-link ";
setInError(vpnLinkStateIid, vpnLinkState, errMsg);
return;
}
// Second VPN
+ if ( VpnUtil.getVpnInstance(this.dataBroker, secondEndpointVpnUuid.getValue()) == null ) {
+ String errMsg = "InterVpnLink " + add.getName() + " creation error: could not find 2nd endpoint Vpn "
+ + secondEndpointVpnUuid.getValue();
+ setInError(vpnLinkStateIid, vpnLinkState, errMsg);
+ return;
+ }
if (!checkVpnAvailability(key, secondEndpointVpnUuid)) {
- String errMsg = String.format("Vpn already associated with a previous inter-vpn-link {}",
- secondEndpointVpnUuid);
- logger.error(errMsg);
+ String errMsg = "InterVpnLink " + add.getName() + " creation error: Vpn " + secondEndpointVpnUuid.getValue()
+ + " is already associated with an inter-vpn-link";
setInError(vpnLinkStateIid, vpnLinkState, errMsg);
return;
}
// TODO: Doing like this we are retrieving operative DPNs from MDSAL when we just need one. Fix it
- List<BigInteger> firstDpnList = VpnUtil.pickRandomDPNs(broker, numberOfDpns, null);
+ List<BigInteger> firstDpnList = VpnUtil.pickRandomDPNs(dataBroker, numberOfDpns, null);
if (firstDpnList != null && !firstDpnList.isEmpty()) {
// TODO: Limitation to be solved later
- // List<BigInteger> secondDpnList = VpnUtil.pickRandomDPNs(broker, numberOfDpns, firstDpnList);
+ // List<BigInteger> secondDpnList = VpnUtil.pickRandomDPNs(dataBroker, numberOfDpns, firstDpnList);
List<BigInteger> secondDpnList = firstDpnList;
- Integer firstVpnLportTag = allocateVpnLinkLportTag(key.getName() + firstEndpointVpnUuid.getValue());
- Integer secondVpnLportTag = allocateVpnLinkLportTag(key.getName() + secondEndpointVpnUuid.getValue());
+ Long firstVpnLportTag = allocateVpnLinkLportTag(key.getName() + firstEndpointVpnUuid.getValue());
+ Long secondVpnLportTag = allocateVpnLinkLportTag(key.getName() + secondEndpointVpnUuid.getValue());
FirstEndpointState firstEndPointState =
new FirstEndpointStateBuilder().setVpnUuid(firstEndpointVpnUuid).setDpId(firstDpnList)
.setLportTag(firstVpnLportTag).build();
new SecondEndpointStateBuilder().setVpnUuid(secondEndpointVpnUuid).setDpId(secondDpnList)
.setLportTag(secondVpnLportTag).build();
- InterVpnLinkUtil.updateInterVpnLinkState(broker, 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(broker, mdsalManager, add, firstDpnList,
- secondEndpointVpnUuid, secondVpnLportTag);
- InterVpnLinkUtil.installLPortDispatcherTableFlow(broker, mdsalManager, add, secondDpnList,
- firstEndpointVpnUuid, firstVpnLportTag);
+ InterVpnLinkUtil.installLPortDispatcherTableFlow(dataBroker, mdsalManager, add, firstDpnList,
+ secondEndpointVpnUuid, secondVpnLportTag);
+ InterVpnLinkUtil.installLPortDispatcherTableFlow(dataBroker, mdsalManager, add, secondDpnList,
+ 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
// to Vpn2 targets. If new Vpn2 targets are added later, the Fib will be maintained in these DPNs even if
// Vpn2 is not physically present there.
- InterVpnLinkUtil.updateVpnToDpnMap(broker, firstDpnList, secondEndpointVpnUuid);
- InterVpnLinkUtil.updateVpnToDpnMap(broker, secondDpnList, firstEndpointVpnUuid);
+ InterVpnLinkUtil.updateVpnToDpnMap(dataBroker, firstDpnList, secondEndpointVpnUuid);
+ InterVpnLinkUtil.updateVpnToDpnMap(dataBroker, secondDpnList, firstEndpointVpnUuid);
// Now, if the corresponding flags are activated, there will be some routes exchange
leakRoutesIfNeeded(add);
} else {
// If there is no connection to DPNs, the InterVpnLink is created and the InterVpnLinkState is also created
// with the corresponding LPortTags but no DPN is assigned since there is no DPN operative.
- Integer firstVpnLportTag = allocateVpnLinkLportTag(key.getName() + firstEndpointVpnUuid.getValue());
- Integer secondVpnLportTag = allocateVpnLinkLportTag(key.getName() + secondEndpointVpnUuid.getValue());
+ Long firstVpnLportTag = allocateVpnLinkLportTag(key.getName() + firstEndpointVpnUuid.getValue());
+ Long secondVpnLportTag = allocateVpnLinkLportTag(key.getName() + secondEndpointVpnUuid.getValue());
FirstEndpointState firstEndPointState =
new FirstEndpointStateBuilder().setVpnUuid(firstEndpointVpnUuid)
.setLportTag(firstVpnLportTag).build();
SecondEndpointState secondEndPointState =
new SecondEndpointStateBuilder().setVpnUuid(secondEndpointVpnUuid)
.setLportTag(secondVpnLportTag).build();
- InterVpnLinkUtil.updateInterVpnLinkState(broker, add.getName(), InterVpnLinkState.State.Error, firstEndPointState,
- secondEndPointState);
+ InterVpnLinkUtil.updateInterVpnLinkState(dataBroker, add.getName(), InterVpnLinkState.State.Error,
+ firstEndPointState, secondEndPointState);
}
leakRoutes(vpnLink, vpn1Uuid, vpn2Uuid, originsToConsider);
// 2nd Endpoint ==> 1st endpoint
- leakRoutes(vpnLink, vpnLink.getSecondEndpoint().getVpnUuid().getValue(),
- vpnLink.getFirstEndpoint().getVpnUuid().getValue(),
- originsToConsider);
+ leakRoutes(vpnLink, vpn2Uuid, vpn1Uuid, originsToConsider);
}
// Static routes in Vpn1 pointing to Vpn2's endpoint
private void leakRoutes(InterVpnLink vpnLink, String srcVpnUuid, String dstVpnUuid,
List<RouteOrigin> originsToConsider) {
- String srcVpnRd = VpnUtil.getVpnRd(broker, srcVpnUuid);
- String dstVpnRd = VpnUtil.getVpnRd(broker, dstVpnUuid);
- List<VrfEntry> srcVpnRemoteVrfEntries = VpnUtil.getVrfEntriesByOrigin(broker, srcVpnRd, originsToConsider);
+ String srcVpnRd = VpnUtil.getVpnRd(dataBroker, srcVpnUuid);
+ String dstVpnRd = VpnUtil.getVpnRd(dataBroker, dstVpnUuid);
+ List<VrfEntry> srcVpnRemoteVrfEntries = VpnUtil.getVrfEntriesByOrigin(dataBroker, srcVpnRd, originsToConsider);
for ( VrfEntry vrfEntry : srcVpnRemoteVrfEntries ) {
long label = VpnUtil.getUniqueId(idManager, VpnConstants.VPN_IDPOOL_NAME,
VpnUtil.getNextHopLabelKey(dstVpnRd, vrfEntry.getDestPrefix()));
- VpnUtil.leakRoute(broker, bgpManager, vpnLink, srcVpnUuid, dstVpnUuid,
- vrfEntry.getDestPrefix(), label);
+ InterVpnLinkUtil.leakRoute(dataBroker, bgpManager, vpnLink, srcVpnUuid, dstVpnUuid, vrfEntry.getDestPrefix(),
+ label);
}
}
*/
private void leakExtraRoutesToVpnEndpoint(InterVpnLink vpnLink, String vpn1Uuid, String vpn2Uuid) {
- String vpn1Rd = VpnUtil.getVpnRd(broker, vpn1Uuid);
+ String vpn1Rd = VpnUtil.getVpnRd(dataBroker, vpn1Uuid);
String vpn2Endpoint = vpnLink.getSecondEndpoint().getIpAddress().getValue();
- List<VrfEntry> allVpnVrfEntries = VpnUtil.getAllVrfEntries(broker, vpn1Rd);
+ List<VrfEntry> allVpnVrfEntries = VpnUtil.getAllVrfEntries(dataBroker, vpn1Rd);
for ( VrfEntry vrfEntry : allVpnVrfEntries ) {
if ( vrfEntry.getNextHopAddressList() != null
&& vrfEntry.getNextHopAddressList().contains(vpn2Endpoint) ) {
long label = VpnUtil.getUniqueId(idManager, VpnConstants.VPN_IDPOOL_NAME,
VpnUtil.getNextHopLabelKey(vpn1Rd, vrfEntry.getDestPrefix()));
- VpnUtil.leakRoute(broker, bgpManager, vpnLink, vpn2Uuid, vpn1Uuid, vrfEntry.getDestPrefix(),
+ InterVpnLinkUtil.leakRoute(dataBroker, bgpManager, vpnLink, vpn2Uuid, vpn1Uuid, vrfEntry.getDestPrefix(),
label, RouteOrigin.value(vrfEntry.getOrigin()));
}
}
private boolean checkVpnAvailability(InterVpnLinkKey key, Uuid vpnId) {
Preconditions.checkNotNull(vpnId);
- List<InterVpnLink> interVpnLinks = VpnUtil.getAllInterVpnLinks(broker);
+ List<InterVpnLink> interVpnLinks = InterVpnLinkUtil.getAllInterVpnLinks(dataBroker);
if ( interVpnLinks != null ) {
for (InterVpnLink interVpnLink : interVpnLinks) {
if (!key.equals(interVpnLink.getKey())
@Override
protected void remove(InstanceIdentifier<InterVpnLink> identifier, InterVpnLink del) {
+ LOG.debug("Reacting to InterVpnLink {} removal", del.getName());
// Remove learnt routes
// Remove entries in the LPortDispatcher table
// Remove the corresponding entries in InterVpnLinkState
// For each endpoint, remove all routes that have been learnt by intervpnLink
String vpn1Uuid = del.getFirstEndpoint().getVpnUuid().getValue();
- String rd1 = VpnUtil.getVpnRdFromVpnInstanceConfig(broker, vpn1Uuid);
- VpnUtil.removeVrfEntriesByOrigin(broker, rd1, RouteOrigin.INTERVPN);
- VpnUtil.removeVrfEntriesByNexthop(broker, rd1, del.getSecondEndpoint().getIpAddress().getValue());
+ String rd1 = VpnUtil.getVpnRdFromVpnInstanceConfig(dataBroker, vpn1Uuid);
+ LOG.debug("Removing leaked routes in VPN {} rd={}", vpn1Uuid, rd1);
+ VpnUtil.removeVrfEntriesByOrigin(dataBroker, rd1, RouteOrigin.INTERVPN);
+ VpnUtil.removeVrfEntriesByNexthop(dataBroker, rd1, del.getSecondEndpoint().getIpAddress().getValue());
String vpn2Uuid = del.getSecondEndpoint().getVpnUuid().getValue();
- String rd2 = VpnUtil.getVpnRdFromVpnInstanceConfig(broker, vpn2Uuid);
- VpnUtil.removeVrfEntriesByOrigin(broker, rd2, RouteOrigin.INTERVPN);
- VpnUtil.removeVrfEntriesByNexthop(broker, rd2, del.getFirstEndpoint().getIpAddress().getValue());
-
- InterVpnLinkState interVpnLinkState = VpnUtil.getInterVpnLinkState(broker, del.getName());
- Integer firstEndpointLportTag = interVpnLinkState.getFirstEndpointState().getLportTag();
-
- Integer secondEndpointLportTag = interVpnLinkState.getSecondEndpointState().getLportTag();
-
- // Remmoving the flow entries in LPortDispatcher table in 1st Endpoint DPNs
- for ( BigInteger dpnId : interVpnLinkState.getFirstEndpointState().getDpId() ) {
- String flowRef = InterVpnLinkUtil.getLportDispatcherFlowRef(del.getName(), secondEndpointLportTag);
- FlowKey flowKey = new FlowKey(new FlowId(flowRef));
- Flow flow = new FlowBuilder().setKey(flowKey).setId(new FlowId(flowRef))
- .setTableId(NwConstants.LPORT_DISPATCHER_TABLE).setFlowName(flowRef)
- .build();
- mdsalManager.removeFlow(dpnId, flow);
-
- // Also remove the 'fake' iface from the VpnToDpn map
- VpnUtil.removeIfaceFromVpnToDpnMap(broker, rd1, dpnId, getInterVpnLinkIfaceName(vpn1Uuid, dpnId));
+ String rd2 = VpnUtil.getVpnRdFromVpnInstanceConfig(dataBroker, vpn2Uuid);
+ LOG.debug("Removing leaked routes in VPN {} rd={}", vpn2Uuid, rd2);
+ VpnUtil.removeVrfEntriesByOrigin(dataBroker, rd2, RouteOrigin.INTERVPN);
+ VpnUtil.removeVrfEntriesByNexthop(dataBroker, rd2, del.getFirstEndpoint().getIpAddress().getValue());
+
+ Optional<InterVpnLinkState> optIVpnLinkState = InterVpnLinkUtil.getInterVpnLinkState(dataBroker, del.getName());
+ if ( optIVpnLinkState.isPresent() ) {
+ InterVpnLinkState interVpnLinkState = optIVpnLinkState.get();
+ Long firstEndpointLportTag = interVpnLinkState.getFirstEndpointState().getLportTag();
+ Long secondEndpointLportTag = interVpnLinkState.getSecondEndpointState().getLportTag();
+ removeVpnLinkEndpointFlows(del.getName(), rd1, vpn1Uuid,
+ interVpnLinkState.getFirstEndpointState().getDpId(),
+ secondEndpointLportTag.intValue(),
+ del.getSecondEndpoint().getIpAddress().getValue());
+ removeVpnLinkEndpointFlows(del.getName(), rd2, vpn2Uuid,
+ interVpnLinkState.getSecondEndpointState().getDpId(),
+ firstEndpointLportTag.intValue(),
+ del.getFirstEndpoint().getIpAddress().getValue());
}
- // Removing the flow entries in 2nd Endpoint DPNs
- for ( BigInteger dpnId : interVpnLinkState.getSecondEndpointState().getDpId() ) {
- String flowRef = InterVpnLinkUtil.getLportDispatcherFlowRef(del.getName(), firstEndpointLportTag);
- FlowKey flowKey = new FlowKey(new FlowId(flowRef));
- Flow flow = new FlowBuilder().setKey(flowKey).setId(new FlowId(flowRef))
- .setTableId(NwConstants.LPORT_DISPATCHER_TABLE).setFlowName(flowRef)
- .build();
- mdsalManager.removeFlow(dpnId, flow);
-
- // Also remove the 'fake' iface from the VpnToDpn map
- VpnUtil.removeIfaceFromVpnToDpnMap(broker, rd2, dpnId, getInterVpnLinkIfaceName(vpn2Uuid, dpnId));
- }
-
- // Release idManager wit LPortTag associated to endpoints
+ // Release idManager with LPortTag associated to endpoints
+ LOG.debug("Releasing InterVpnLink {} endpoints LportTags", del.getName());
InterVpnLinkKey key = del.getKey();
Uuid firstEndpointVpnUuid = del.getFirstEndpoint().getVpnUuid();
Uuid secondEndpointVpnUuid = del.getSecondEndpoint().getVpnUuid();
// At this point. we need to check if is there any entry in FIB table pointing to LPortDispatcher table.
// Remove it in that case.
- // 1stEndPoint dpns
- for ( BigInteger dpnId : interVpnLinkState.getFirstEndpointState().getDpId() ) {
- removeRouteFromInterVpnLink(dpnId, del.getName(), del.getSecondEndpoint().getIpAddress().getValue());
- }
+ // Removing the InterVpnLinkState
+ InstanceIdentifier<InterVpnLinkState> interVpnLinkStateIid = InterVpnLinkUtil.getInterVpnLinkStateIid(del.getName());
+ VpnUtil.delete(dataBroker, LogicalDatastoreType.CONFIGURATION, interVpnLinkStateIid);
+ }
- // 2ndtEndPoint dpns
- for ( BigInteger dpnId : interVpnLinkState.getSecondEndpointState().getDpId() ) {
- removeRouteFromInterVpnLink(dpnId, del.getName(), del.getFirstEndpoint().getIpAddress().getValue());
+ private void removeVpnLinkEndpointFlows( String interVpnLinkName, String rd, String vpnUuid, List<BigInteger> dpns,
+ int otherEndpointLportTag, String otherEndpointIpAddr ) {
+ LOG.debug("Removing endpoint flows for vpn {}. InterVpnLink={}. OtherEndpointLportTag={}",
+ vpnUuid, interVpnLinkName, otherEndpointLportTag);
+ if ( dpns == null ) {
+ LOG.debug("VPN {} endpoint is not instantiated in any DPN for InterVpnLink {}",
+ vpnUuid, interVpnLinkName);
+ return;
}
- // Removing the InterVpnLinkState
- InstanceIdentifier<InterVpnLinkState> interVpnLinkStateIid = VpnUtil.getInterVpnLinkStateIid(del.getName());
- VpnUtil.delete(broker, LogicalDatastoreType.CONFIGURATION, interVpnLinkStateIid);
+ for ( BigInteger dpnId : dpns ) {
+ try {
+ // Removing flow from LportDispatcher table
+ String flowRef = InterVpnLinkUtil.getLportDispatcherFlowRef(interVpnLinkName, otherEndpointLportTag);
+ FlowKey flowKey = new FlowKey(new FlowId(flowRef));
+ Flow flow = new FlowBuilder().setKey(flowKey).setId(new FlowId(flowRef))
+ .setTableId(NwConstants.LPORT_DISPATCHER_TABLE).setFlowName(flowRef)
+ .build();
+ mdsalManager.removeFlow(dpnId, flow);
+
+ // Removing flow from Fib table
+ String fibFlowRef = getInterVpnFibFlowRef(dpnId, NwConstants.L3_FIB_TABLE, interVpnLinkName,
+ otherEndpointIpAddr);
+ FlowKey fibFlowKey = new FlowKey(new FlowId(fibFlowRef));
+ Flow fibFlow = new FlowBuilder().setKey(fibFlowKey).setId(new FlowId(fibFlowRef))
+ .setTableId(NwConstants.L3_FIB_TABLE).setFlowName(fibFlowRef).build();
+ mdsalManager.removeFlow(dpnId, fibFlow);
+
+ // Also remove the 'fake' iface from the VpnToDpn map
+ VpnUtil.removeIfaceFromVpnToDpnMap(dataBroker, rd, dpnId, getInterVpnLinkIfaceName(vpnUuid, dpnId));
+
+ } catch ( Exception e ) {
+ // Whatever happens it should not stop it from trying to remove as much as possible
+ LOG.warn("Error while removing InterVpnLink {} Endpoint flows on dpn {}. Reason: {}",
+ interVpnLinkName, dpnId, e);
+ }
+ }
}
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);
}
// TODO
}
- private String getInterVpnFibFlowRef(BigInteger dpnId, short tableId, String interVpnLinkName, String nextHop ) {
- return new StringBuilder(64).append(VpnConstants.FLOWID_PREFIX).append(dpnId).append(NwConstants.FLOWID_SEPARATOR)
- .append(tableId).append(NwConstants.FLOWID_SEPARATOR)
- .append(interVpnLinkName).append(NwConstants.FLOWID_SEPARATOR)
- .append(nextHop).toString();
+ private String getInterVpnFibFlowRef(BigInteger dpnId, short tableId, String interVpnLinkName, String nextHop ) {
+ return new StringBuilder(64).append(VpnConstants.FLOWID_PREFIX).append(dpnId)
+ .append(NwConstants.FLOWID_SEPARATOR).append(tableId)
+ .append(NwConstants.FLOWID_SEPARATOR).append(interVpnLinkName)
+ .append(NwConstants.FLOWID_SEPARATOR).append(nextHop)
+ .toString();
}
- private void removeRouteFromInterVpnLink(BigInteger dpnId, String interVpnLinkName, final String nextHop) {
- String flowRef = getInterVpnFibFlowRef(dpnId, NwConstants.L3_FIB_TABLE, interVpnLinkName, nextHop);
- FlowKey flowKey = new FlowKey(new FlowId(flowRef));
- Flow flow = new FlowBuilder().setKey(flowKey).setId(new FlowId(flowRef))
- .setTableId(NwConstants.L3_FIB_TABLE).setFlowName(flowRef)
- .build();
- mdsalManager.removeFlow(dpnId, flow);
- }
-
-
- private Integer allocateVpnLinkLportTag(String idKey) {
+ private Long 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()) {
- return rpcResult.getResult().getIdValue().intValue();
+ if (rpcResult.isSuccessful()) {
+ return rpcResult.getResult().getIdValue();
} else {
- logger.warn("RPC Call to Get Unique Id returned with Errors {}", rpcResult.getErrors());
+ LOG.warn("RPC Call to Get Unique Id returned with Errors {}", rpcResult.getErrors());
}
} catch (InterruptedException | ExecutionException e) {
- logger.warn("Exception when getting Unique Id",e);
+ LOG.warn("Exception when getting Unique Id",e);
}
return INVALID_ID;
}
protected void setInError(final InstanceIdentifier<InterVpnLinkState> vpnLinkStateIid,
final InterVpnLinkState vpnLinkState,
String errorMsg) {
+ LOG.error("Setting InterVpnLink {} in error. Reason: {}", vpnLinkState.getInterVpnLinkName(), errorMsg);
// Setting InterVPNLink in error state in MDSAL
InterVpnLinkState vpnLinkErrorState =
- new InterVpnLinkStateBuilder(vpnLinkState).setState(InterVpnLinkState.State.Error)
- .setErrorDescription(errorMsg)
- .build();
- WriteTransaction tx = broker.newWriteOnlyTransaction();
+ new InterVpnLinkStateBuilder(vpnLinkState).setState(InterVpnLinkState.State.Error)
+ .setErrorDescription(errorMsg)
+ .build();
+ WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
tx.put(LogicalDatastoreType.CONFIGURATION, vpnLinkStateIid, vpnLinkErrorState, true);
tx.submit();
Futures.addCallback(eventFuture, new FutureCallback<Object>() {
@Override
public void onFailure(Throwable error) {
- logger.warn("Error when sending notification about InterVpnLink creation issue. InterVpnLink name={}. Error={}",
+ LOG.warn("Error when sending notification about InterVpnLink creation issue. InterVpnLink name={}. Error={}",
vpnLinkState.getInterVpnLinkName(), vpnLinkState, error);
}
@Override
public void onSuccess(Object arg) {
- logger.trace("Error notification for InterVpnLink successfully sent. VpnLink={} error={}",
+ LOG.trace("Error notification for InterVpnLink successfully sent. VpnLink={} error={}",
vpnLinkState.getInterVpnLinkName(), vpnLinkState);
}
});