import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.netvirt.vpnmanager.api.IVpnManager;
import org.opendaylight.genius.mdsalutil.AbstractDataChangeListener;
-import org.opendaylight.genius.itm.globals.ITMConstants;
import org.opendaylight.genius.mdsalutil.ActionInfo;
import org.opendaylight.genius.mdsalutil.ActionType;
import org.opendaylight.genius.mdsalutil.FlowEntity;
import org.opendaylight.genius.mdsalutil.MetaDataUtil;
import org.opendaylight.genius.mdsalutil.NwConstants;
import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.SubnetRoute;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.PrefixToInterface;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceOpData;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.RdToElanOp;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.rd.to.elan.op.RdToElanOpEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.rd.to.elan.op.RdToElanOpEntryKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnToExtraroute;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.VpnIds;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.VpnIdsKey;
NwConstants.TABLE_MISS_PRIORITY, "Subnet Route Table Miss", 0, 0, COOKIE_TABLE_MISS, matches, instructions);
if (addOrRemove == NwConstants.ADD_FLOW) {
- LOG.debug("Invoking MDSAL to install SubnetRoute Table Miss Entries for DPN" + dpnId);
mdsalManager.installFlow(flowEntity);
} else {
- LOG.debug("Invoking MDSAL to remove SubnetRoute Table Miss Entries for DPN " + dpnId);
mdsalManager.removeFlow(flowEntity);
}
}
createTerminatingServiceActions(dpId, (int)label, actionsInfos);
- LOG.debug("Terminating service Entry for dpID {} : label : {} egress : {} installed successfully {}",
+ LOG.debug("Terminating service Entry for dpID {} : label : {} egress : {} installed successfully",
dpId, label, groupId);
}
5, String.format("%s:%d","TST Flow Entry ",label), 0, 0,
COOKIE_TUNNEL.add(BigInteger.valueOf(label)), mkMatches, null);
mdsalManager.removeFlow(flowEntity);
- LOG.debug("Terminating service Entry for dpID {} : label : {} removed successfully {}",dpId, label);
+ LOG.debug("Terminating service Entry for dpID {} : label : {} removed successfully",dpId, label);
}
public BigInteger deleteLocalFibEntry(Long vpnId, String rd, VrfEntry vrfEntry) {
final long vpnId, final VrfTablesKey vrfTableKey,
final VrfEntry vrfEntry) {
String rd = vrfTableKey.getRouteDistinguisher();
- LOG.debug("adding route " + vrfEntry.getDestPrefix() + " " + rd);
+ LOG.debug("createremotefibentry: adding route {} for rd {}", vrfEntry.getDestPrefix(), rd);
/********************************************/
String tunnelInterface = resolveAdjacency(localDpnId, remoteDpnId, vpnId, vrfEntry, rd);
if(tunnelInterface == null) {
}
**/
makeConnectedRoute(remoteDpnId, vpnId, vrfEntry, rd, instructions, NwConstants.ADD_FLOW);
- LOG.debug("Successfully added fib entry for " + vrfEntry.getDestPrefix() + " vpnId " + vpnId);
+ LOG.debug("Successfully added fib entry for prefix {} in vpn {} ", vrfEntry.getDestPrefix(), vpnId);
}
private void delIntfFromDpnToVpnList(long vpnId, BigInteger dpnId, String intfName, String rd) {
- prefix to interface entry
- vpn interface op DS
*/
+ LOG.debug("Cleanup of prefix {} in VPN {}", vrfEntry.getDestPrefix(), vpnId);
Prefixes prefixInfo = getPrefixToInterface(vpnId, vrfEntry.getDestPrefix());
Extraroute extraRoute = null;
if (prefixInfo == null) {
if(extraRoute != null) {
prefixInfo = getPrefixToInterface(vpnId, extraRoute.getNexthopIp() + "/32");
//clean up the vpn to extra route entry in DS
- FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, FibUtil.getVpnToExtrarouteIdentifier(rd, vrfEntry.getDestPrefix()));
+ //FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, FibUtil.getVpnToExtrarouteIdentifier(rd,
+ // vrfEntry.getDestPrefix()));
}
}
if (prefixInfo == null) {
- LOG.debug("Cleanup VPN Data Failed as unable to find prefix Info for " + vrfEntry.getDestPrefix());
+ LOG.debug("Cleanup VPN Data Failed as unable to find prefix Info for prefix {}" , vrfEntry.getDestPrefix());
return; //Don't have any info for this prefix (shouldn't happen); need to return
}
String ifName = prefixInfo.getVpnInterfaceName();
- Optional<Adjacencies> optAdjacencies = FibUtil.read(broker, LogicalDatastoreType.OPERATIONAL, FibUtil.getAdjListPath(ifName));
- int numAdj = 0;
- if (optAdjacencies.isPresent()) {
- numAdj = optAdjacencies.get().getAdjacency().size();
- }
- LOG.trace("cleanUpOpDataForFib: remove adjacency for prefix: {} {}", vpnId, vrfEntry.getDestPrefix());
- //remove adjacency corr to prefix
- if (numAdj > 1) {
- FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL,
- FibUtil.getAdjacencyIdentifier(ifName, vrfEntry.getDestPrefix()));
- }
+ synchronized (ifName.intern()) {
+ Optional<VpnInterface> optvpnInterface = FibUtil.read(broker, LogicalDatastoreType.OPERATIONAL, FibUtil.getVpnInterfaceIdentifier(ifName));
+ if (optvpnInterface.isPresent()) {
+ long associatedVpnId = FibUtil.getVpnId(broker, optvpnInterface.get().getVpnInstanceName());
+ if (vpnId != associatedVpnId) {
+ LOG.warn("Prefixes {} are associated with different vpn instance with id : {} rather than {}",
+ vrfEntry.getDestPrefix(), associatedVpnId, vpnId);
+ LOG.trace("Releasing prefix label - rd {}, prefix {}", rd, vrfEntry.getDestPrefix());
+ FibUtil.releaseId(idManager, FibConstants.VPN_IDPOOL_NAME,
+ FibUtil.getNextHopLabelKey(rd, vrfEntry.getDestPrefix()));
+ LOG.warn("Not proceeding with Cleanup op data for prefix {}", vrfEntry.getDestPrefix());
+ return;
+ } else {
+ LOG.debug("Processing cleanup of prefix {} associated with vpn {}", vrfEntry.getDestPrefix(), associatedVpnId);
+ }
+ }
+ if (extraRoute != null) {
+ FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, FibUtil.getVpnToExtrarouteIdentifier(rd, vrfEntry.getDestPrefix()));
+ }
+ Optional<Adjacencies> optAdjacencies = FibUtil.read(broker, LogicalDatastoreType.OPERATIONAL, FibUtil.getAdjListPath(ifName));
+ int numAdj = 0;
+ if (optAdjacencies.isPresent()) {
+ numAdj = optAdjacencies.get().getAdjacency().size();
+ }
- if ((numAdj - 1) == 0) { //there are no adjacencies left for this vpn interface, clean up
- //clean up the vpn interface from DpnToVpn list
- LOG.trace("Clean up vpn interface {} from dpn {} to vpn {} list.", ifName, prefixInfo.getDpnId(), rd);
- FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL,
- FibUtil.getVpnInterfaceIdentifier(ifName));
- }
+ //remove adjacency corr to prefix
+ if (numAdj > 1) {
+ LOG.trace("cleanUpOpDataForFib: remove adjacency for prefix: {} {}", vpnId, vrfEntry.getDestPrefix());
+ FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL,
+ FibUtil.getAdjacencyIdentifier(ifName, vrfEntry.getDestPrefix()));
+ }
- FibUtil.releaseId(idManager, FibConstants.VPN_IDPOOL_NAME,
- FibUtil.getNextHopLabelKey(rd, vrfEntry.getDestPrefix()));
+ if ((numAdj - 1) == 0) { //there are no adjacencies left for this vpn interface, clean up
+ //clean up the vpn interface from DpnToVpn list
+ LOG.trace("Clean up vpn interface {} from dpn {} to vpn {} list.", ifName, prefixInfo.getDpnId(), rd);
+ FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL,
+ FibUtil.getVpnInterfaceIdentifier(ifName));
+ }
+ FibUtil.releaseId(idManager, FibConstants.VPN_IDPOOL_NAME,
+ FibUtil.getNextHopLabelKey(rd, vrfEntry.getDestPrefix()));
+ }
}
private void deleteFibEntries(final InstanceIdentifier<VrfEntry> identifier,
String values[] = vrfEntry.getDestPrefix().split("/");
String ipAddress = values[0];
int prefixLength = (values.length == 1) ? 0 : Integer.parseInt(values[1]);
- LOG.debug("Adding route to DPN. ip {} masklen {}", ipAddress, prefixLength);
+ if (addOrRemove == NwConstants.ADD_FLOW) {
+ LOG.debug("Adding route to DPN {} for rd {} prefix {} ", dpId, rd, vrfEntry.getDestPrefix());
+ } else {
+ LOG.debug("Removing route from DPN {} for rd {} prefix {}", dpId, rd, vrfEntry.getDestPrefix());
+ }
InetAddress destPrefix = null;
try {
destPrefix = InetAddress.getByName(ipAddress);
} catch (UnknownHostException e) {
- LOG.error("UnknowHostException in addRoute. Failed to add Route for ipPrefix {}", vrfEntry.getDestPrefix());
+ LOG.error("Failed to get destPrefix for prefix {} ", vrfEntry.getDestPrefix(), e);
return;
}
makeConnectedRoute(dpnId, vpnId, vrfEntry, rd, null, NwConstants.DEL_FLOW);
makeLFibTableEntry(dpnId, vrfEntry.getLabel(), null,
vrfEntry.getNextHopAddress(),NwConstants.DEL_FLOW);
- FibUtil.releaseId(idManager, FibConstants.VPN_IDPOOL_NAME,
- FibUtil.getNextHopLabelKey(rd, vrfEntry.getDestPrefix()));
LOG.trace("cleanUpDpnForVpn: Released subnetroute label {} for rd {} prefix {}", vrfEntry.getLabel(), rd,
vrfEntry.getDestPrefix());
continue;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adjacencies;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
}
}
+ static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to
+ .vpn.id.VpnInstance>
+ getVpnInstanceToVpnIdIdentifier(String vpnName) {
+ return InstanceIdentifier.builder(VpnInstanceToVpnId.class)
+ .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
+ .VpnInstance.class,
+ new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
+ .VpnInstanceKey(vpnName)).build();
+ }
+
+ static long getVpnId(DataBroker broker, String vpnName) {
+
+ InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
+ .VpnInstance> id
+ = getVpnInstanceToVpnIdIdentifier(vpnName);
+ Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
+ .VpnInstance> vpnInstance
+ = read(broker, LogicalDatastoreType.CONFIGURATION, id);
+
+ long vpnId = -1;
+ if(vpnInstance.isPresent()) {
+ vpnId = vpnInstance.get().getVpnId();
+ }
+ return vpnId;
+ }
+
static final FutureCallback<Void> DEFAULT_CALLBACK =
new FutureCallback<Void>() {
public void onSuccess(Void result) {
container subnet-op-data {
+ config false;
list subnet-op-data-entry {
key subnet-id;
leaf subnet-id {
}
container port-op-data {
+ config false;
list port-op-data-entry {
key port-id;
leaf port-id {
}
}
- container rd-to-elan-op{
- list rd-to-elan-op-entry{
- key "rd subnet-ip";
- leaf rd {
- type string;
- }
- leaf subnet-ip {
- type string;
- }
- leaf next-hop-ip {
- type string;
- }
- leaf vpn-name {
- type string;
- }
- leaf elan-tag{
- type uint32;
- }
- }
- }
-
grouping dpn-in-vpn-event {
leaf dpn-id { type uint64; }
leaf vpn-name { type string; }
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-binding-broker-impl</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.netvirt</groupId>
+ <artifactId>natservice-api</artifactId>
+ <version>${vpnservices.version}</version>
+ </dependency>
</dependencies>
<!--
public static final BigInteger COOKIE_VM_INGRESS_TABLE = new BigInteger("8000001", 16);
public static final BigInteger COOKIE_L3_BASE = new BigInteger("8000000", 16);
public static final String FLOWID_PREFIX = "L3.";
- public static final long MIN_WAIT_TIME_IN_MILLISECONDS = 10000;
+ public static final long MIN_WAIT_TIME_IN_MILLISECONDS = 5000;
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;
public static final short ELAN_SMAC_TABLE = 50;
public static final short FIB_TABLE = 21;
public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface> implements AutoCloseable {
private static final Logger LOG = LoggerFactory.getLogger(VpnInterfaceManager.class);
private ListenerRegistration<DataChangeListener> listenerRegistration, opListenerRegistration;
- private ConcurrentMap<String, Runnable> vpnIntfMap = new ConcurrentHashMap<>();
private static final ThreadFactory threadFactory = new ThreadFactoryBuilder()
.setNameFormat("NV-VpnIntfMgr-%d").build();
- private ExecutorService executorService = Executors.newSingleThreadExecutor(threadFactory);
private final DataBroker broker;
private final IBgpManager bgpManager;
private IFibManager fibManager;
private OdlArputilService arpManager;
private NeutronvpnService neuService;
private VpnSubnetRouteHandler vpnSubnetRouteHandler;
+ private ConcurrentHashMap<String, Runnable> vpnIntfMap = new ConcurrentHashMap<String, Runnable>();
+ private ExecutorService executorService = Executors.newSingleThreadExecutor();
private InterfaceStateChangeListener interfaceListener;
private VpnInterfaceOpListener vpnInterfaceOpListener;
private ArpNotificationHandler arpNotificationHandler;
LOG.trace("VpnInstance to VPNId mapping is not yet available, bailing out now.");
return;
}
+ boolean waitForVpnInterfaceOpRemoval = false;
+ int numAdjs = 0;
+ VpnInterface opVpnInterface = null;
synchronized (interfaceName.intern()) {
- if (VpnUtil.getOperationalVpnInterface(broker, vpnInterface.getName()) != null) {
- LOG.trace("VPN Interface already provisioned , bailing out from here.");
+ opVpnInterface = VpnUtil.getOperationalVpnInterface(broker, vpnInterface.getName());
+ if (opVpnInterface != null ) {
+ String opVpnName = opVpnInterface.getVpnInstanceName();
+ String primaryInterfaceIp = null;
+ if(opVpnName.equals(vpnName)) {
+ // Please check if the primary VRF Entry does not exist for VPNInterface
+ // If so, we have to process ADD, as this might be a DPN Restart with Remove and Add triggered
+ // back to back
+ // However, if the primary VRF Entry for this VPNInterface exists, please continue bailing out !
+ List<Adjacency> adjs = VpnUtil.getAdjacenciesForVpnInterfaceFromConfig(broker, interfaceName);
+ if (adjs == null) {
+ LOG.info("VPN Interface {} addition failed as adjacencies for this vpn interface could not be obtained",
+ interfaceName);
+ return;
+ }
+ numAdjs = adjs.size();
+ for (Adjacency adj : adjs) {
+ if (adj.getMacAddress() != null && !adj.getMacAddress().isEmpty()) {
+ primaryInterfaceIp = adj.getNextHopIp();
+ break;
+ }
+ }
+ if (primaryInterfaceIp == null) {
+ LOG.info("VPN Interface {} addition failed as primary adjacency for this vpn interface could not be obtained",
+ interfaceName);
+ return;
+ }
+ // Get the rd of the vpn instance
+ String rd = getRouteDistinguisher(opVpnName);
+ VrfEntry vrf = VpnUtil.getVrfEntry(broker, rd, primaryInterfaceIp);
+ if (vrf != null) {
+ LOG.info("VPN Interface {} already provisioned , bailing out from here.", interfaceName);
+ return;
+ }
+ waitForVpnInterfaceOpRemoval = true;
+ } else {
+ LOG.info("vpn interface {} to go to configured vpn {}, but in operational vpn {}", interfaceName, vpnName, opVpnName);
+ }
+ }
+ if (!waitForVpnInterfaceOpRemoval) {
+ // Add the VPNInterface and quit
+ bindService(dpId, vpnName, interfaceName, lPortTag);
+ updateDpnDbs(dpId, vpnName, interfaceName, true);
+ processVpnInterfaceAdjacencies(dpId, VpnUtil.getVpnInterfaceIdentifier(vpnInterface.getName()), vpnInterface);
return;
}
+ }
+
+ // FIB didn't get a chance yet to clean up this VPNInterface
+ // Let us give it a chance here !
+ LOG.info("VPN Interface {} waiting for FIB to clean up! ", interfaceName);
+ try {
+ Runnable notifyTask = new VpnNotifyTask();
+ vpnIntfMap.put(interfaceName, notifyTask);
+ synchronized (notifyTask) {
+ try {
+ notifyTask.wait(VpnConstants.MAX_WAIT_TIME_IN_MILLISECONDS);
+ } catch (InterruptedException e) {
+ }
+ }
+ } finally {
+ vpnIntfMap.remove(interfaceName);
+ }
+
+ opVpnInterface = VpnUtil.getOperationalVpnInterface(broker, interfaceName);
+ if (opVpnInterface != null) {
+ LOG.error("VPN Interface {} removal by FIB did not complete on time, bailing addition ...", interfaceName);
+ return;
+ }
+ // VPNInterface got removed, proceed with Add
+ synchronized (interfaceName.intern()) {
bindService(dpId, vpnName, interfaceName, lPortTag);
updateDpnDbs(dpId, vpnName, interfaceName, true);
processVpnInterfaceAdjacencies(dpId, VpnUtil.getVpnInterfaceIdentifier(vpnInterface.getName()), vpnInterface);
}
-
}
private void updateDpnDbs(BigInteger dpId, String vpnName, String interfaceName, boolean add) {
removeAdjacenciesFromVpn(identifier, vpnInterface);
LOG.info("Unbinding vpn service from interface {} ", interfaceName);
unbindService(dpId, vpnName, interfaceName, lPortTag, isInterfaceStateDown);
+ }
- //wait till DCN for removal of vpn interface in operational DS arrives
+ // FIB didn't get a chance yet to clean up this VPNInterface
+ // Let us give it a chance here !
+ LOG.info("VPN Interface {} removal waiting for FIB to clean up ! ", interfaceName);
+ try {
Runnable notifyTask = new VpnNotifyTask();
- synchronized (interfaceName.intern()) {
- vpnIntfMap.put(interfaceName, notifyTask);
- synchronized (notifyTask) {
- try {
- notifyTask.wait(VpnConstants.MIN_WAIT_TIME_IN_MILLISECONDS);
- } catch (InterruptedException e) {
- }
+ vpnIntfMap.put(interfaceName, notifyTask);
+ synchronized (notifyTask) {
+ try {
+ notifyTask.wait(VpnConstants.PER_INTERFACE_MAX_WAIT_TIME_IN_MILLISECONDS);
+ } catch (InterruptedException e) {
}
}
-
+ } finally {
+ vpnIntfMap.remove(interfaceName);
}
+
}
private void removeAdjacenciesFromVpn(final InstanceIdentifier<VpnInterface> identifier, VpnInterface intf) {
private void unbindService(BigInteger dpId, String vpnInstanceName, String vpnInterfaceName,
int lPortTag, boolean isInterfaceStateDown) {
if (!isInterfaceStateDown) {
- VpnUtil.delete(broker, LogicalDatastoreType.CONFIGURATION,
+ MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION,
InterfaceUtils.buildServiceId(vpnInterfaceName,
- VpnConstants.L3VPN_SERVICE_IDENTIFIER),
- VpnUtil.DEFAULT_CALLBACK);
+ VpnConstants.L3VPN_SERVICE_IDENTIFIER));
}
long vpnId = VpnUtil.getVpnId(broker, vpnInstanceName);
makeArpFlow(dpId, VpnConstants.L3VPN_SERVICE_IDENTIFIER, lPortTag, vpnInterfaceName,
private void removePrefixFromBGP(String rd, String prefix) {
+ removeFibEntryFromDS(rd, prefix);
try {
- bgpManager.deletePrefix(rd, prefix);
+ bgpManager.withdrawPrefix(rd, prefix);
} catch(Exception e) {
LOG.error("Delete prefix failed", e);
}
InstanceIdentifierBuilder<VrfEntry> idBuilder =
InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)).child(VrfEntry.class, new VrfEntryKey(prefix));
InstanceIdentifier<VrfEntry> vrfEntryId = idBuilder.build();
- VpnUtil.delete(broker, LogicalDatastoreType.CONFIGURATION, vrfEntryId, VpnUtil.DEFAULT_CALLBACK);
+ MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, vrfEntryId);
}
VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
prefixToInterface.get().getIpAddress()),
VpnUtil.DEFAULT_CALLBACK);
- updateDpnDbs(prefixToInterface.get().getDpnId(), del.getVpnInstanceName(), interfaceName, false);
- }
- Long ifCnt = 0L;
- ifCnt = vpnInstOp.getVpnInterfaceCount();
- LOG.trace("VpnInterfaceOpListener removed: interface name {} rd {} vpnName {} Intf count {}",
- interfaceName, rd, vpnName, ifCnt);
- if ((ifCnt != null) && (ifCnt > 0)) {
- VpnUtil.asyncUpdate(broker, LogicalDatastoreType.OPERATIONAL,
- VpnUtil.getVpnInstanceOpDataIdentifier(rd),
- VpnUtil.updateIntfCntInVpnInstOpData(ifCnt - 1, rd), VpnUtil.DEFAULT_CALLBACK);
+ synchronized (interfaceName.intern()) {
+ updateDpnDbs(prefixToInterface.get().getDpnId(), del.getVpnInstanceName(), interfaceName, false);
+ }
}
+// Long ifCnt = 0L;
+// //ifCnt = vpnInstOp.getVpnInterfaceCount();
+// LOG.trace("VpnInterfaceOpListener removed: interface name {} rd {} vpnName {} Intf count {}",
+// interfaceName, rd, vpnName, ifCnt);
+// if ((ifCnt != null) && (ifCnt > 0)) {
+// VpnUtil.asyncUpdate(broker, LogicalDatastoreType.OPERATIONAL,
+// VpnUtil.getVpnInstanceOpDataIdentifier(rd),
+// VpnUtil.updateIntfCntInVpnInstOpData(ifCnt - 1, rd), VpnUtil.DEFAULT_CALLBACK);
+// }
}
} else {
LOG.error("rd not retrievable as vpninstancetovpnid for vpn {} is absent, trying rd as ", vpnName, vpnName);
private void notifyTaskIfRequired(String intfName) {
Runnable notifyTask = vpnIntfMap.remove(intfName);
if (notifyTask == null) {
+ LOG.trace("VpnInterfaceOpListener update: No Notify Task queued for vpnInterface {}", intfName);
return;
}
executorService.execute(notifyTask);
@Override
protected void update(InstanceIdentifier<VpnInterface> identifier, VpnInterface original, VpnInterface update) {
+ final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class);
+ String interfaceName = key.getName();
+
+ if (original.getVpnInstanceName().equals(update.getVpnInstanceName())) {
+ return;
+ }
+
+ //increment the vpn interface count in Vpn Instance Op Data
+ //Long ifCnt = 0L;
+ VpnInstanceOpDataEntry vpnInstOp = null;
+// InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to
+// .vpn.id.VpnInstance>
+// updId = VpnUtil.getVpnInstanceToVpnIdIdentifier(update.getVpnInstanceName());
+// Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
+// .VpnInstance> updVpnInstance
+// = VpnUtil.read(broker, LogicalDatastoreType.CONFIGURATION, updId);
+//
+// if (updVpnInstance.isPresent()) {
+// String rd = null;
+// rd = updVpnInstance.get().getVrfId();
+//
+// vpnInstOp = VpnUtil.getVpnInstanceOpData(broker, rd);
+//
+// if (vpnInstOp != null && vpnInstOp.getVpnInterfaceCount() != null) {
+// ifCnt = vpnInstOp.getVpnInterfaceCount();
+// }
+//
+// LOG.trace("VpnInterfaceOpListener update: interface name {} rd {} interface count in updated Vpn Op
+// Instance {}", interfaceName, rd, ifCnt);
+//
+// VpnUtil.asyncUpdate(broker, LogicalDatastoreType.OPERATIONAL,
+// VpnUtil.getVpnInstanceOpDataIdentifier(rd),
+// VpnUtil.updateIntfCntInVpnInstOpData(ifCnt + 1, rd), VpnUtil.DEFAULT_CALLBACK);
+// }
+
+ InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to
+ .vpn.id.VpnInstance>
+ origId = VpnUtil.getVpnInstanceToVpnIdIdentifier(original.getVpnInstanceName());
+ Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
+ .VpnInstance> origVpnInstance
+ = VpnUtil.read(broker, LogicalDatastoreType.CONFIGURATION, origId);
+
+ if (origVpnInstance.isPresent()) {
+ String rd = null;
+ rd = origVpnInstance.get().getVrfId();
+
+ vpnInstOp = VpnUtil.getVpnInstanceOpData(broker, rd);
+ LOG.trace("VpnInterfaceOpListener updated: interface name {} original rd {} original vpnName {}",
+ interfaceName, rd, original.getVpnInstanceName());
+
+ if (vpnInstOp != null) {
+ Adjacency adjacency = original.getAugmentation(Adjacencies.class).getAdjacency().get(0);
+ Optional<Prefixes> prefixToInterface = Optional.absent();
+ prefixToInterface = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL,
+ VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
+ VpnUtil.getIpPrefix(adjacency.getIpAddress())));
+ if (!prefixToInterface.isPresent()) {
+ prefixToInterface = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL,
+ VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
+ VpnUtil.getIpPrefix(adjacency.getNextHopIp())));
+ }
+ if (prefixToInterface.isPresent()) {
+// VpnUtil.delete(broker, LogicalDatastoreType.OPERATIONAL,
+// VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
+// prefixToInterface.get().getIpAddress()),
+// VpnUtil.DEFAULT_CALLBACK);
+ synchronized (interfaceName.intern()) {
+ updateDpnDbs(prefixToInterface.get().getDpnId(), original.getVpnInstanceName(), interfaceName, false);
+ }
+ }
+ }
+ }
+ notifyTaskIfRequired(interfaceName);
+// if (vpnInstOp != null && vpnInstOp.getVpnInterfaceCount() != null) {
+// ifCnt = vpnInstOp.getVpnInterfaceCount();
+// } else {
+// LOG.debug("VpnInterfaceOpListener update: Vpn interface count not recoverable from original, to handle update for rd {}", rd);
+// return;
+// }
+// LOG.trace("VpnInterfaceOpListener update: interface name {} rd {} interface count in original Vpn Op Instance {}", interfaceName, rd, ifCnt);
+//
+// if (ifCnt > 0) {
+// VpnUtil.asyncUpdate(broker, LogicalDatastoreType.OPERATIONAL,
+// VpnUtil.getVpnInstanceOpDataIdentifier(rd),
+// VpnUtil.updateIntfCntInVpnInstOpData(ifCnt - 1, rd), VpnUtil.DEFAULT_CALLBACK);
+// }
+// }
}
@Override
String interfaceName = key.getName();
//increment the vpn interface count in Vpn Instance Op Data
- Long ifCnt = 0L;
- String rd = getRouteDistinguisher(add.getVpnInstanceName());
- if(rd == null || rd.isEmpty()) rd = add.getVpnInstanceName();
- VpnInstanceOpDataEntry vpnInstOp = VpnUtil.getVpnInstanceOpData(broker, rd);
- if(vpnInstOp != null && vpnInstOp.getVpnInterfaceCount() != null) {
- ifCnt = vpnInstOp.getVpnInterfaceCount();
- }
-
- LOG.trace("VpnInterfaceOpListener add: interface name {} rd {} interface count in Vpn Op Instance {}", interfaceName, rd, ifCnt);
-
- VpnUtil.asyncUpdate(broker, LogicalDatastoreType.OPERATIONAL,
- VpnUtil.getVpnInstanceOpDataIdentifier(rd),
- VpnUtil.updateIntfCntInVpnInstOpData(ifCnt + 1, rd), VpnUtil.DEFAULT_CALLBACK);
-
+// Long ifCnt = 0L;
+// String rd = getRouteDistinguisher(add.getVpnInstanceName());
+// if(rd == null || rd.isEmpty()) rd = add.getVpnInstanceName();
+// VpnInstanceOpDataEntry vpnInstOp = VpnUtil.getVpnInstanceOpData(broker, rd);
+// if(vpnInstOp != null && vpnInstOp.getVpnInterfaceCount() != null) {
+// ifCnt = vpnInstOp.getVpnInterfaceCount();
+// }
+//
+// LOG.trace("VpnInterfaceOpListener add: interface name {} rd {} interface count in Vpn Op Instance {}",
+// interfaceName, rd, ifCnt);
+//
+// VpnUtil.asyncUpdate(broker, LogicalDatastoreType.OPERATIONAL,
+// VpnUtil.getVpnInstanceOpDataIdentifier(rd),
+// VpnUtil.updateIntfCntInVpnInstOpData(ifCnt + 1, rd), VpnUtil.DEFAULT_CALLBACK);
}
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op
+ .data.entry.VpnToDpnList;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
this.vpnInterfaceManager = vpnInterfaceManager;
}
- private void waitForOpRemoval(String id, long timeout) {
+ private void waitForOpRemoval(String rd, String vpnName) {
//wait till DCN for update on VPN Instance Op Data signals that vpn interfaces linked to this vpn instance is zero
- Runnable notifyTask = new VpnNotifyTask();
- synchronized (id.intern()) {
- try {
- vpnOpMap.put(id, notifyTask);
- synchronized (notifyTask) {
- try {
- notifyTask.wait(timeout);
- } catch (InterruptedException e) {
+ //TODO(vpnteam): Entire code would need refactoring to listen only on the parent object - VPNInstance
+ VpnInstanceOpDataEntry vpnOpEntry = null;
+ Long intfCount = 0L;
+ Long currentIntfCount = 0L;
+ long timeout = VpnConstants.MIN_WAIT_TIME_IN_MILLISECONDS;
+ Optional<VpnInstanceOpDataEntry> vpnOpValue = null;
+ vpnOpValue = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL,
+ VpnUtil.getVpnInstanceOpDataIdentifier(rd));
+
+ if ((vpnOpValue != null) && (vpnOpValue.isPresent())) {
+ vpnOpEntry = vpnOpValue.get();
+ List<VpnToDpnList> dpnToVpns = vpnOpEntry.getVpnToDpnList();
+ if (dpnToVpns != null) {
+ for (VpnToDpnList dpn : dpnToVpns) {
+ if (dpn.getVpnInterfaces() != null) {
+ intfCount = intfCount + dpn.getVpnInterfaces().size();
}
}
- } finally {
- vpnOpMap.remove(id);
}
- }
+ //intfCount = vpnOpEntry.getVpnInterfaceCount();
+ while (true) {
+ if (intfCount > 0) {
+ // Minimum wait time of 5 seconds for one VPN Interface clearance (inclusive of full trace on)
+ timeout = intfCount * VpnConstants.MIN_WAIT_TIME_IN_MILLISECONDS;
+ // Maximum wait time of 90 seconds for all VPN Interfaces clearance (inclusive of full trace on)
+ if (timeout > VpnConstants.MAX_WAIT_TIME_IN_MILLISECONDS) {
+ timeout = VpnConstants.MAX_WAIT_TIME_IN_MILLISECONDS;
+ }
+ LOG.info("VPNInstance removal count of interface at {} for for rd {}, vpnname {}",
+ intfCount, rd, vpnName);
+ }
+ LOG.info("VPNInstance removal thread waiting for {} seconds for rd {}, vpnname {}",
+ (timeout / 1000), rd, vpnName);
+ try {
+ Thread.sleep(timeout);
+ } catch (java.lang.InterruptedException e) {
+ }
+// Runnable notifyTask = new VpnNotifyTask();
+// synchronized (rd.intern()) {
+// try {
+// vpnOpMap.put(rd, notifyTask);
+// synchronized (notifyTask) {
+// try {
+// notifyTask.wait(timeout);
+// } catch (InterruptedException e) {
+// }
+// }
+// } finally {
+// vpnOpMap.remove(rd);
+// }
+// }
+
+ // Check current interface count
+ vpnOpValue = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL,
+ VpnUtil.getVpnInstanceOpDataIdentifier(rd));
+ if ((vpnOpValue != null) && (vpnOpValue.isPresent())) {
+ vpnOpEntry = vpnOpValue.get();
+ dpnToVpns = vpnOpEntry.getVpnToDpnList();
+ currentIntfCount = 0L;
+ if (dpnToVpns != null) {
+ for (VpnToDpnList dpn : dpnToVpns) {
+ if (dpn.getVpnInterfaces() != null) {
+ currentIntfCount = currentIntfCount + dpn.getVpnInterfaces().size();
+ }
+ }
+ }
+ //currentIntfCount = vpnOpEntry.getVpnInterfaceCount();
+ if ((currentIntfCount == 0) || (currentIntfCount >= intfCount)) {
+ // Either the FibManager completed its job to cleanup all vpnInterfaces in VPN
+ // OR
+ // There is no progress by FibManager in removing all the interfaces even after good time!
+ // In either case, let us quit and take our chances.
+ //TODO(vpnteam): L3VPN refactoring to take care of this case.
+ LOG.info("VPNInstance bailing out of wait loop as currentIntfCount is {} for for rd {}, vpnname {}",
+ currentIntfCount, rd, vpnName);
+ break;
+ } else {
+ // There is some progress by FibManager, so let us give it some more time!
+ intfCount = currentIntfCount;
+ }
+ } else {
+ // There is no VPNOPEntry. Something else happened on the system !
+ // So let us quit and take our chances.
+ //TODO(vpnteam): L3VPN refactoring to take care of this case.
+ break;
+ }
+ }
+ }
+ LOG.info("Returned out of waiting for Op Data removal for rd {}, vpnname {}", rd, vpnName);
}
@Override
VpnUtil.getVpnInstanceOpDataIdentifier(vpnName));
}
- if ((vpnOpValue != null) && (vpnOpValue.isPresent())) {
- VpnInstanceOpDataEntry vpnOpEntry = null;
- long timeout = VpnConstants.MIN_WAIT_TIME_IN_MILLISECONDS;
- Long intfCount = 0L;
-
- vpnOpEntry = vpnOpValue.get();
- intfCount = vpnOpEntry.getVpnInterfaceCount();
- if (intfCount != null && intfCount > 0) {
- // Minimum wait time of 10 seconds for one VPN Interface clearance (inclusive of full trace on)
- timeout = intfCount * 10000;
- // Maximum wait time of 90 seconds for all VPN Interfaces clearance (inclusive of full trace on)
- if (timeout > VpnConstants.MAX_WAIT_TIME_IN_MILLISECONDS) {
- timeout = VpnConstants.MAX_WAIT_TIME_IN_MILLISECONDS;
- }
- LOG.trace("VPNInstance removal count of interface at {} for for rd {}, vpnname {}",
- intfCount, rd, vpnName);
- }
- LOG.trace("VPNInstance removal thread waiting for {} seconds for rd {}, vpnname {}",
- (timeout/1000), rd, vpnName);
-
- if ((rd != null) && (!rd.isEmpty())) {
- waitForOpRemoval(rd, timeout);
- } else {
- waitForOpRemoval(vpnName, timeout);
- }
-
- LOG.trace("Returned out of waiting for Op Data removal for rd {}, vpnname {}", rd, vpnName);
+ if ((rd != null) && (!rd.isEmpty())) {
+ waitForOpRemoval(rd, vpnName);
+ } else {
+ waitForOpRemoval(vpnName, vpnName);
}
// Clean up VpnInstanceToVpnId from Config DS
VpnUtil.removeVpnInstanceToVpnId(broker, vpnName);
fibManager.setConfTransType("L3VPN", "VXLAN");
LOG.trace("setting it to vxlan now");
} catch (Exception e) {
- LOG.trace("Exception caught setting the cached value for transportType");
LOG.error(e.getMessage());
}
} else {
final VpnInstanceOpDataEntryKey key = identifier.firstKeyOf(VpnInstanceOpDataEntry.class, VpnInstanceOpDataEntryKey.class);
String vpnName = key.getVrfId();
- LOG.trace("VpnInstanceOpListener update: vpn name {} interface count in Old VpnOp Instance {} in New VpnOp Instance {}" ,
- vpnName, original.getVpnInterfaceCount(), update.getVpnInterfaceCount() );
-
- //if((original.getVpnToDpnList().size() != update.getVpnToDpnList().size()) && (update.getVpnToDpnList().size() == 0)) {
- if((original.getVpnInterfaceCount() != update.getVpnInterfaceCount()) && (update.getVpnInterfaceCount() == 0)) {
- notifyTaskIfRequired(vpnName);
- }
- }
-
- private void notifyTaskIfRequired(String vpnName) {
- Runnable notifyTask = vpnOpMap.remove(vpnName);
- if (notifyTask == null) {
- LOG.trace("VpnInstanceOpListener update: No Notify Task queued for vpnName {}", vpnName);
- return;
- }
- executorService.execute(notifyTask);
- }
+// LOG.trace("VpnInstanceOpListener update: vpn name {} interface count in Old VpnOp Instance {} in New " +
+// "VpnOp Instance {}" ,
+// vpnName, original.getVpnInterfaceCount(), update.getVpnInterfaceCount() );
+//
+// //if((original.getVpnToDpnList().size() != update.getVpnToDpnList().size()) && (update.getVpnToDpnList()
+// .size() == 0)) {
+// if((original.getVpnInterfaceCount() != update.getVpnInterfaceCount()) && (update.getVpnInterfaceCount()
+// == 0)) {
+// notifyTaskIfRequired(vpnName);
+// }
+ }
+
+// private void notifyTaskIfRequired(String vpnName) {
+// Runnable notifyTask = vpnOpMap.remove(vpnName);
+// if (notifyTask == null) {
+// LOG.trace("VpnInstanceOpListener update: No Notify Task queued for vpnName {}", vpnName);
+// return;
+// }
+// executorService.execute(notifyTask);
+// }
@Override
protected void add(InstanceIdentifier<VpnInstanceOpDataEntry> identifier, VpnInstanceOpDataEntry add) {
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
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.genius.idmanager.rev160406.IdManagerService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.*;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.port.op.data.PortOpDataEntry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.port.op.data.PortOpDataEntryKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.rd.to.elan.op.RdToElanOpEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.rd.to.elan.op.RdToElanOpEntryBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.rd.to.elan.op.RdToElanOpEntryKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.SubnetOpDataEntry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.SubnetOpDataEntryKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.SubnetOpDataEntryBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.subnet.op.data.entry.SubnetToDpn;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.subnet.op.data.entry.subnet.to.dpn.VpnInterfaces;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import java.math.BigInteger;
Preconditions.checkNotNull(vpnName, "VpnName cannot be null or empty!");
Preconditions.checkNotNull(elanTag, "ElanTag cannot be null or empty!");
- logger.info("onSubnetAddedToVpn: Subnet" + subnetId.getValue() + " being added to vpn");
+ logger.info("onSubnetAddedToVpn: Subnet " + subnetId.getValue() + " being added to vpn");
//TODO(vivek): Change this to use more granularized lock at subnetId level
synchronized (this) {
try {
+ Subnetmap subMap = null;
+
+ // Please check if subnetId belongs to an External Network
+ InstanceIdentifier<Subnetmap> subMapid = InstanceIdentifier.builder(Subnetmaps.class).
+ child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
+ Optional<Subnetmap> sm = VpnUtil.read(broker, LogicalDatastoreType.CONFIGURATION, subMapid);
+ if (!sm.isPresent()) {
+ logger.error("onSubnetAddedToVpn: Unable to retrieve subnetmap entry for subnet : " + subnetId);
+ return;
+ }
+ subMap = sm.get();
+ InstanceIdentifier<Networks> netsIdentifier = InstanceIdentifier.builder(ExternalNetworks.class).
+ child(Networks.class, new NetworksKey(subMap.getNetworkId())).build();
+ Optional<Networks> optionalNets = VpnUtil.read(broker, LogicalDatastoreType.CONFIGURATION, netsIdentifier);
+ if (optionalNets.isPresent()) {
+ logger.info("onSubnetAddedToVpn: subnet {} is an external subnet on external network {}, so ignoring this for SubnetRoute",
+ subnetId.getValue(), subMap.getNetworkId().getValue());
+ return;
+ }
//Create and add SubnetOpDataEntry object for this subnet to the SubnetOpData container
InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier = InstanceIdentifier.builder(SubnetOpData.class).
child(SubnetOpDataEntry.class, new SubnetOpDataEntryKey(subnetId)).build();
subOpBuilder.setElanTag(elanTag);
// First recover set of ports available in this subnet
- InstanceIdentifier<Subnetmap> subMapid = InstanceIdentifier.builder(Subnetmaps.class).
- child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
- Optional<Subnetmap> sm = VpnUtil.read(broker, LogicalDatastoreType.CONFIGURATION, subMapid);
- if (!sm.isPresent()) {
- logger.error("onSubnetAddedToVpn: Unable to retrieve subnetmap entry for subnet : " + subnetId);
- return;
- }
- Subnetmap subMap = sm.get();
List<Uuid> portList = subMap.getPortList();
if (portList != null) {
for (Uuid port: portList) {
if (!notification.isExternalVpn()) {
return;
}
- logger.info("onSubnetDeletedFromVpn: Subnet" + subnetId.getValue() + " being removed to vpn");
+ logger.info("onSubnetDeletedFromVpn: Subnet " + subnetId.getValue() + " being removed to vpn");
//TODO(vivek): Change this to use more granularized lock at subnetId level
synchronized (this) {
try {
String subnetIp = subOpBuilder.getSubnetCidr();
BigInteger nhDpnId = subOpBuilder.getNhDpnId();
MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, subOpIdentifier);
- logger.trace("Removed subnetopdataentry successfully to CONFIG Datastore");
+ logger.info("onSubnetDeletedFromVpn: Removed subnetopdataentry for subnet {} successfully from Datastore", subnetId.getValue());
try {
//Withdraw the routes for all the interfaces on this subnet
//Remove subnet route entry from FIB
try {
// Write the Subnet Route Entry to FIB
// Advertise BGP Route here and set route_adv_state to DONE
- int label = 0;
- VrfEntry vrf = VpnUtil.getVrfEntry(broker, rd, subnetIp);
- if (vrf != null) {
- label = (vrf.getLabel()).intValue();
- } else {
- label = getLabel(rd, subnetIp);
- }
+ int label = getLabel(rd, subnetIp);
addSubnetRouteToFib(rd, subnetIp, nhDpnId, vpnName, elanTag, label);
advertiseSubnetRouteToBgp(rd, subnetIp, nhDpnId, vpnName, elanTag, label);
subOpBuilder.setRouteAdvState(TaskState.Done);
// Best effort Withdrawal of route from BGP for this subnet
// Advertise the new NexthopIP to BGP for this subnet
//withdrawSubnetRoutefromBgp(rd, subnetIp);
- int label = 0;
- VrfEntry vrf = VpnUtil.getVrfEntry(broker, rd, subnetIp);
- if (vrf != null) {
- label = (vrf.getLabel()).intValue();
- } else {
- label = getLabel(rd, subnetIp);
- }
+ int label = getLabel(rd, subnetIp);
addSubnetRouteToFib(rd, subnetIp, nhDpnId, vpnName, elanTag, label);
advertiseSubnetRouteToBgp(rd, subnetIp, nhDpnId, vpnName, elanTag, label);
subOpBuilder.setRouteAdvState(TaskState.Done);
try {
// Write the Subnet Route Entry to FIB
// Advertise BGP Route here and set route_adv_state to DONE
- int label = 0;
- VrfEntry vrf = VpnUtil.getVrfEntry(broker, rd, subnetIp);
- if (vrf != null) {
- label = (vrf.getLabel()).intValue();
- } else {
- label = getLabel(rd, subnetIp);
- }
+ int label = getLabel(rd, subnetIp);
addSubnetRouteToFib(rd, subnetIp, nhDpnId, vpnName, elanTag, label);
advertiseSubnetRouteToBgp(rd, subnetIp, nhDpnId, vpnName, elanTag, label);
subOpBuilder.setRouteAdvState(TaskState.Done);
try {
// Best effort Withdrawal of route from BGP for this subnet
//withdrawSubnetRoutefromBgp(rd, subnetIp);
- int label = 0;
- VrfEntry vrf = VpnUtil.getVrfEntry(broker, rd, subnetIp);
- if (vrf != null) {
- label = (vrf.getLabel()).intValue();
- } else {
- label = getLabel(rd, subnetIp);
- }
+ int label = getLabel(rd, subnetIp);
addSubnetRouteToFib(rd, subnetIp, nhDpnId, vpnName, elanTag, label);
advertiseSubnetRouteToBgp(rd, subnetIp, nhDpnId, vpnName, elanTag, label);
subOpBuilder.setRouteAdvState(TaskState.Done);
throw new Exception("Unable to obtain endpointIp address for DPNId " + nhDpnId);
}
try {
+ // BGPManager (inside ODL) requires a withdraw followed by advertise
+ // due to bugs with ClusterDataChangeListener used by BGPManager.
+ bgpManager.withdrawPrefix(rd, subnetIp);
bgpManager.advertisePrefix(rd, subnetIp, nexthopIp, label);
} catch (Exception e) {
logger.error("Subnet route not advertised for rd " + rd + " failed ", e);
new ExtrarouteKey(ipPrefix)).build();
}
+ static List<Adjacency> getAdjacenciesForVpnInterfaceFromConfig(DataBroker broker, String intfName) {
+ final InstanceIdentifier<VpnInterface> identifier = getVpnInterfaceIdentifier(intfName);
+ InstanceIdentifier<Adjacencies> path = identifier.augmentation(Adjacencies.class);
+ Optional<Adjacencies> adjacencies = VpnUtil.read(broker, LogicalDatastoreType.CONFIGURATION, path);
+
+ if (adjacencies.isPresent()) {
+ List<Adjacency> nextHops = adjacencies.get().getAdjacency();
+ return nextHops;
+ }
+ return null;
+ }
+
static Extraroute getVpnToExtraroute(String ipPrefix, String nextHop) {
return new ExtrarouteBuilder().setPrefix(ipPrefix).setNexthopIp(nextHop).build();
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.PortOpData;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.PortOpDataBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.SubnetOpData;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.RdToElanOp;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.TaskState;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.port.op.data.PortOpDataEntry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.port.op.data.PortOpDataEntryBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.port.op.data.PortOpDataEntryKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.rd.to.elan.op.RdToElanOpEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.rd.to.elan.op.RdToElanOpEntryBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.rd.to.elan.op.RdToElanOpEntryKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.SubnetOpDataEntry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.SubnetOpDataEntryBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.SubnetOpDataEntryKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.RpcResult;
SubnetUpdatedInVpn subnetUpdatedInVpn = null;
SubnetDeletedFromVpn subnetDeletedFromVpn = null;
SubnetToDpn subnetToDpn = null;
- RdToElanOpEntry rdToElanOpEntry = null;
String subnetIp = "10.1.1.24";
String routeDistinguisher = "100:1";
String nexthopIp = null;
String idKey = null;
AllocateIdOutput allocateIdOutput = null;
AllocateIdInput allocateIdInput = null;
+ Networks networks = null;
org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance vpnInstnce;
InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
InstanceIdentifier<Subnetmap> subMapid = InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class, new
SubnetmapKey(subnetId)).build();
InstanceIdentifier<PortOpData> portOpIdentifr = InstanceIdentifier.builder(PortOpData.class).build();
- InstanceIdentifier<RdToElanOpEntry> rdIdentifier = InstanceIdentifier.builder(RdToElanOp.class).
- child(RdToElanOpEntry.class, new RdToElanOpEntryKey(interfaceName, subnetIp)).build();
InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
.VpnInstance> instVpnInstance = getVpnInstanceToVpnIdIdentifier(interfaceName);
InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.
.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance.class,
new org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances
.VpnInstanceKey(interfaceName)).build();
+ InstanceIdentifier<Networks> netsIdentifier = InstanceIdentifier.builder(ExternalNetworks.class).
+ child(Networks.class, new NetworksKey(portId)).build();
@Mock DataBroker dataBroker;
@Mock ListenerRegistration<DataChangeListener> dataChangeListenerRegistration;
Optional<PortOpDataEntry> optionalPortOp;
Optional<PortOpData> optionalPtOp;
Optional<Subnetmap> optionalSubnetMap;
- Optional<RdToElanOpEntry> optionalRd;
Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance>
optionalVpnInstnce;
Optional<org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance>
vpnInstanceOptional;
+ Optional<Networks> optionalNetworks;
@Before
public void setUp() throws Exception {
optionalPortOp = Optional.of(portOp);
optionalPtOp = Optional.of(portOpData);
optionalSubnetMap = Optional.of(subnetmap);
- optionalRd = Optional.of(rdToElanOpEntry);
optionalVpnInstnce = Optional.of(vpnInstance);
vpnInstanceOptional = Optional.of(vpnInstnce);
+ optionalNetworks = Optional.of(networks);
- doReturn(Futures.immediateCheckedFuture(optionalRd)).when(mockReadTx).read(LogicalDatastoreType.OPERATIONAL,
- rdIdentifier);
doReturn(Futures.immediateCheckedFuture(optionalIfState)).when(mockReadTx).read(LogicalDatastoreType
.OPERATIONAL, ifStateId);
doReturn(Futures.immediateCheckedFuture(optionalSubs)).when(mockReadTx).read(LogicalDatastoreType
.CONFIGURATION, instVpnInstance);
doReturn(Futures.immediateCheckedFuture(vpnInstanceOptional)).when(mockReadTx).read(LogicalDatastoreType
.CONFIGURATION,vpnInstanceIdentifier);
+ doReturn(Futures.immediateCheckedFuture(Optional.absent())).when(mockReadTx).read(LogicalDatastoreType
+ .CONFIGURATION,netsIdentifier);
doReturn(idOutputOptional).when(idManager).allocateId(allocateIdInput);
}
.setSubnetIp(subnetIp).setVpnName(interfaceName).setElanTag(elanTag).build();
subnetOp = new SubnetOpDataEntryBuilder().setElanTag(elanTag).setNhDpnId(dpId).setSubnetCidr(subnetIp)
.setSubnetId(subnetId).setKey(new SubnetOpDataEntryKey(subnetId)).setVpnName(interfaceName)
- .setVrfId(routeDistinguisher).setSubnetToDpn(subToDpn).setRouteAdvState(TaskState.Pending).build();
+ .setVrfId(routeDistinguisher).setSubnetToDpn(subToDpn).setRouteAdvState(TaskState.Done).build();
vpnInstance = new VpnInstanceBuilder().setVpnId(elanTag).setVpnInstanceName(interfaceName).setVrfId
(interfaceName).setKey(new VpnInstanceKey(interfaceName)).build();
subnetmap = new SubnetmapBuilder().setSubnetIp(subnetIp).setId(subnetId).setNetworkId(portId).setKey(new
tunlEndPts = new TunnelEndPointsBuilder().setInterfaceName(interfaceName).setVLANID(10).setIpAddress
(ipAddress).build();
tunnelEndPoints.add(tunlEndPts);
- rdToElanOpEntry = new RdToElanOpEntryBuilder().setElanTag(elanTag).setRd(interfaceName).setVpnName
- (interfaceName).setNextHopIp(nexthopIp)
- .setKey(new RdToElanOpEntryKey(interfaceName, subnetIp)).setSubnetIp(subnetIp).build();
ipv4Family = new Ipv4FamilyBuilder().setRouteDistinguisher(routeDistinguisher).build();
vpnInstnce = new org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances
.VpnInstanceBuilder().setKey(new org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn
.rev140815.vpn.instances.VpnInstanceKey(interfaceName)).setVpnInstanceName(interfaceName)
.setIpv4Family(ipv4Family).build();
+ networks = new NetworksBuilder().setId(portId).setKey(new NetworksKey(portId)).build();
doReturn(mockReadTx).when(dataBroker).newReadOnlyTransaction();
doReturn(mockWriteTx).when(dataBroker).newWriteOnlyTransaction();
doReturn(Futures.immediateCheckedFuture(null)).when(mockWriteTx).submit();