X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=vpnmanager%2Fimpl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fnetvirt%2Fvpnmanager%2FVpnUtil.java;h=c486d3a0ed6deb4e0be3b6897bf4eaec89e33906;hb=72065f5143b3d4a5d0715999aeb35397c34e46d9;hp=bb94820554ac052da4717b3fa31e874bf29598a6;hpb=e81277ac57d2a80c4b211da5b7865de0af23a080;p=netvirt.git diff --git a/vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnUtil.java b/vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnUtil.java old mode 100755 new mode 100644 index bb94820554..c486d3a0ed --- a/vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnUtil.java +++ b/vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnUtil.java @@ -8,12 +8,15 @@ package org.opendaylight.netvirt.vpnmanager; +import static java.util.Collections.emptyList; +import static java.util.Objects.requireNonNull; +import static org.opendaylight.genius.infra.Datastore.OPERATIONAL; + import com.google.common.base.Optional; import com.google.common.collect.Iterators; +import com.google.common.net.InetAddresses; import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.MoreExecutors; import java.math.BigInteger; import java.net.Inet4Address; import java.net.Inet6Address; @@ -30,6 +33,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Map.Entry; +import java.util.Objects; import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; @@ -37,11 +41,21 @@ import java.util.function.Predicate; import java.util.stream.Collectors; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import javax.inject.Singleton; import org.opendaylight.controller.md.sal.binding.api.DataBroker; -import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; +import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; +import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker; +import org.opendaylight.genius.infra.Datastore; +import org.opendaylight.genius.infra.Datastore.Configuration; +import org.opendaylight.genius.infra.Datastore.Operational; import org.opendaylight.genius.infra.ManagedNewTransactionRunner; +import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl; +import org.opendaylight.genius.infra.TypedReadTransaction; +import org.opendaylight.genius.infra.TypedReadWriteTransaction; +import org.opendaylight.genius.infra.TypedWriteTransaction; import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager; import org.opendaylight.genius.mdsalutil.FlowEntity; import org.opendaylight.genius.mdsalutil.FlowEntityBuilder; @@ -56,19 +70,22 @@ import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable; import org.opendaylight.genius.mdsalutil.instructions.InstructionWriteMetadata; import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager; import org.opendaylight.genius.mdsalutil.matches.MatchEthernetDestination; +import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType; import org.opendaylight.genius.mdsalutil.matches.MatchMetadata; import org.opendaylight.genius.utils.ServiceIndex; import org.opendaylight.genius.utils.SystemPropertyReader; import org.opendaylight.infrautils.jobcoordinator.JobCoordinator; +import org.opendaylight.infrautils.utils.concurrent.ListenableFutures; import org.opendaylight.netvirt.bgpmanager.api.IBgpManager; import org.opendaylight.netvirt.elanmanager.api.ElanHelper; -import org.opendaylight.netvirt.fibmanager.api.FibHelper; +import org.opendaylight.netvirt.fibmanager.api.IFibManager; import org.opendaylight.netvirt.fibmanager.api.RouteOrigin; import org.opendaylight.netvirt.neutronvpn.api.enums.IpVersionChoice; import org.opendaylight.netvirt.neutronvpn.interfaces.INeutronVpnManager; import org.opendaylight.netvirt.vpnmanager.api.InterfaceUtils; import org.opendaylight.netvirt.vpnmanager.api.VpnExtraRouteHelper; import org.opendaylight.netvirt.vpnmanager.api.VpnHelper; +import org.opendaylight.netvirt.vpnmanager.iplearn.model.MacEntry; import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig; import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances; import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces; @@ -78,9 +95,9 @@ import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev14081 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceBuilder; import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey; import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.vpn._interface.VpnInstanceNames; -import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.vpn._interface.VpnInstanceNames.AssociatedSubnetType; -import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.vpn._interface.VpnInstanceNamesBuilder; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; @@ -92,12 +109,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406. 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.IdPools; 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.genius.idmanager.rev160406.ReleaseIdOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.id.pools.IdPool; -import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.id.pools.IdPoolKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.IfIndexesInterfaceMap; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._if.indexes._interface.map.IfIndexInterface; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._if.indexes._interface.map.IfIndexInterfaceKey; @@ -106,6 +120,10 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpc import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetInterfaceFromIfIndexOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.ipv6.nd.util.rev170210.Ipv6NdUtilService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.ipv6.nd.util.rev170210.SendNeighborSolicitationToOfGroupInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.ipv6.nd.util.rev170210.SendNeighborSolicitationToOfGroupInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.ipv6.nd.util.rev170210.SendNeighborSolicitationToOfGroupOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.LockManagerService; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.TimeUnits; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.TryLockInput; @@ -136,6 +154,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev15033 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTablesKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentrybase.RoutePaths; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.L3nexthop; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.l3nexthop.VpnNexthops; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.l3nexthop.VpnNexthopsKey; @@ -147,15 +166,13 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Lea import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.LearntVpnVipToPortEventAction; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.LearntVpnVipToPortEventData; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.PrefixToInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.RouterInterfaces; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.SubnetOpData; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.SubnetsAssociatedToRouteTargets; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnIdToVpnInstance; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceOpData; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInterfaceOpData; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnToExtraroutes; 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.adjacency.list.Adjacency.AdjacencyType; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPortBuilder; @@ -164,24 +181,27 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.lea import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.event.data.LearntVpnVipToPortEventBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.event.data.LearntVpnVipToPortEventKey; 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.VpnIdsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.VpnIdsKey; 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.prefix.to._interface.vpn.ids.PrefixesBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces.RouterInterface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces.RouterInterfaceBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces.RouterInterfaceKey; 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.subnets.associated.to.route.targets.RouteTarget; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnets.associated.to.route.targets.RouteTargetKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnets.associated.to.route.targets.route.target.AssociatedSubnet; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnets.associated.to.route.targets.route.target.AssociatedSubnetKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnets.associated.to.route.targets.route.target.associated.subnet.AssociatedVpn; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnets.associated.to.route.targets.route.target.associated.subnet.AssociatedVpnBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnets.associated.to.route.targets.route.target.associated.subnet.AssociatedVpnKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntry; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntryBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntryKey; 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.VpnTargets; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpntargets.VpnTarget; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstanceBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroutes.Vpn; @@ -203,7 +223,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev16011 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkAttributes.NetworkType; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkMaps; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.RouterInterfacesMap; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMap; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapKey; @@ -225,14 +244,28 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.s import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcResult; -import org.opendaylight.yangtools.yang.data.impl.schema.tree.SchemaValidationFailedException; +import org.opendaylight.yangtools.yang.data.api.schema.tree.ModifiedNodeDoesNotExistException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +@Singleton public final class VpnUtil { + private static final Logger LOG = LoggerFactory.getLogger(VpnUtil.class); - private static final int DEFAULT_PREFIX_LENGTH = 32; - private static final String PREFIX_SEPARATOR = "/"; + + public static final int SINGLE_TRANSACTION_BROKER_NO_RETRY = 1; + + private final DataBroker dataBroker; + private final IdManagerService idManager; + private final IFibManager fibManager; + private final IBgpManager bgpManager; + private final LockManagerService lockManager; + private final INeutronVpnManager neutronVpnService; + private final IMdsalApiManager mdsalManager; + private final IInterfaceManager interfaceManager; + private final JobCoordinator jobCoordinator; + private final ManagedNewTransactionRunner txRunner; + private final OdlInterfaceRpcService ifmRpcService; /** * Class to generate timestamps with microsecond precision. @@ -258,90 +291,100 @@ public final class VpnUtil { } } - private VpnUtil() { + public VpnUtil(DataBroker dataBroker, IdManagerService idManager, IFibManager fibManager, + IBgpManager bgpManager, LockManagerService lockManager, INeutronVpnManager neutronVpnService, + IMdsalApiManager mdsalManager, JobCoordinator jobCoordinator, IInterfaceManager interfaceManager, + OdlInterfaceRpcService ifmRpcService) { + this.dataBroker = dataBroker; + this.idManager = idManager; + this.fibManager = fibManager; + this.bgpManager = bgpManager; + this.lockManager = lockManager; + this.neutronVpnService = neutronVpnService; + this.mdsalManager = mdsalManager; + this.interfaceManager = interfaceManager; + this.jobCoordinator = jobCoordinator; + this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker); + this.ifmRpcService = ifmRpcService; } - static InstanceIdentifier getVpnInterfaceIdentifier(String vpnInterfaceName) { + public static InstanceIdentifier getVpnInterfaceIdentifier(String vpnInterfaceName) { return InstanceIdentifier.builder(VpnInterfaces.class) - .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).build(); + .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).build(); } - static InstanceIdentifier getVpnInterfaceOpDataEntryIdentifier( - String vpnInterfaceName, String vpnName) { - return InstanceIdentifier.builder(VpnInterfaceOpData.class) - .child(VpnInterfaceOpDataEntry.class, + static InstanceIdentifier getVpnInterfaceOpDataEntryIdentifier(String vpnInterfaceName, + String vpnName) { + return InstanceIdentifier.builder(VpnInterfaceOpData.class).child(VpnInterfaceOpDataEntry.class, new VpnInterfaceOpDataEntryKey(vpnInterfaceName, vpnName)).build(); } static InstanceIdentifier getVpnInstanceIdentifier(String vpnName) { return InstanceIdentifier.builder(VpnInstances.class) - .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build(); + .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build(); } - static VpnInterface getVpnInterface(DataBroker broker, String vpnInterfaceName) { + @Nullable + VpnInterface getVpnInterface(String vpnInterfaceName) { InstanceIdentifier id = getVpnInterfaceIdentifier(vpnInterfaceName); - Optional vpnInterface = read(broker, LogicalDatastoreType.CONFIGURATION, id); + Optional vpnInterface = read(LogicalDatastoreType.CONFIGURATION, id); return vpnInterface.isPresent() ? vpnInterface.get() : null; } - static VpnInterfaceOpDataEntry getVpnInterfaceOpDataEntry(String intfName, String vpnName, - AdjacenciesOp aug, BigInteger dpnId, - Boolean isSheduledForRemove, long lportTag, String gwMac) { - return new VpnInterfaceOpDataEntryBuilder().setKey(new VpnInterfaceOpDataEntryKey(intfName, vpnName)) - .setDpnId(dpnId).setScheduledForRemove(isSheduledForRemove).addAugmentation(AdjacenciesOp.class, aug) + static VpnInterfaceOpDataEntry getVpnInterfaceOpDataEntry(String intfName, String vpnName, AdjacenciesOp aug, + BigInteger dpnId, long lportTag, + String gwMac) { + return new VpnInterfaceOpDataEntryBuilder().withKey(new VpnInterfaceOpDataEntryKey(intfName, vpnName)) + .setDpnId(dpnId).addAugmentation(AdjacenciesOp.class, aug) .setLportTag(lportTag).setGatewayMacAddress(gwMac).build(); } - static Optional getVpnInterfaceOpDataEntry(DataBroker broker, - String vpnInterfaceName, String vpnName) { + Optional getVpnInterfaceOpDataEntry(String vpnInterfaceName, String vpnName) { InstanceIdentifier id = getVpnInterfaceOpDataEntryIdentifier(vpnInterfaceName, vpnName); - Optional vpnInterfaceOpDataEntry = read(broker, - LogicalDatastoreType.OPERATIONAL, id); + Optional vpnInterfaceOpDataEntry = read(LogicalDatastoreType.OPERATIONAL, + id); return vpnInterfaceOpDataEntry; } - static VpnInstanceNames getVpnInterfaceVpnInstanceNames(String vpnName, AssociatedSubnetType subnetType) { - return new VpnInstanceNamesBuilder().setVpnName(vpnName).setAssociatedSubnetType(subnetType).build(); - } - static InstanceIdentifier getPrefixToInterfaceIdentifier(long vpnId, String ipPrefix) { - return InstanceIdentifier.builder(PrefixToInterface.class) - .child(VpnIds.class, new VpnIdsKey(vpnId)).child(Prefixes.class, - new PrefixesKey(ipPrefix)).build(); + return InstanceIdentifier.builder(PrefixToInterface.class).child(VpnIds.class, new VpnIdsKey(vpnId)) + .child(Prefixes.class, new PrefixesKey(ipPrefix)).build(); } - public static InstanceIdentifier getPrefixToInterfaceIdentifier(long vpnId) { - return InstanceIdentifier.builder(PrefixToInterface.class) - .child(VpnIds.class, new VpnIdsKey(vpnId)).build(); + static InstanceIdentifier getPrefixToInterfaceIdentifier(long vpnId) { + return InstanceIdentifier.builder(PrefixToInterface.class).child(VpnIds.class, new VpnIdsKey(vpnId)).build(); } - static VpnIds getPrefixToInterface(long vpnId) { - return new VpnIdsBuilder().setKey(new VpnIdsKey(vpnId)).setVpnId(vpnId).build(); + static Prefixes getPrefixToInterface(BigInteger dpId, String vpnInterfaceName, String ipPrefix, + Uuid networkId, NetworkType networkType, Long segmentationId, Prefixes.PrefixCue prefixCue) { + return new PrefixesBuilder().setDpnId(dpId).setVpnInterfaceName( + vpnInterfaceName).setIpAddress(ipPrefix)//.setSubnetId(subnetId) + .setNetworkId(networkId).setNetworkType(networkType).setSegmentationId(segmentationId) + .setPrefixCue(prefixCue).build(); } - static Prefixes getPrefixToInterface(BigInteger dpId, String vpnInterfaceName, String ipPrefix, Uuid subnetId, + static Prefixes getPrefixToInterface(BigInteger dpId, String vpnInterfaceName, String ipPrefix, Prefixes.PrefixCue prefixCue) { - return new PrefixesBuilder().setDpnId(dpId).setVpnInterfaceName( - vpnInterfaceName).setIpAddress(ipPrefix).setSubnetId(subnetId).setPrefixCue(prefixCue).build(); + return new PrefixesBuilder().setDpnId(dpId).setVpnInterfaceName(vpnInterfaceName).setIpAddress(ipPrefix) + .setPrefixCue(prefixCue).build(); } - static Optional getPrefixToInterface(DataBroker broker, long vpnId, String ipPrefix) { - return read(broker, LogicalDatastoreType.OPERATIONAL, - getPrefixToInterfaceIdentifier(vpnId, getIpPrefix(ipPrefix))); + Optional getPrefixToInterface(long vpnId, String ipPrefix) { + return read(LogicalDatastoreType.OPERATIONAL, getPrefixToInterfaceIdentifier(vpnId, getIpPrefix(ipPrefix))); } /** * Get VRF table given a Route Distinguisher. * - * @param broker dataBroker service reference * @param rd Route-Distinguisher * @return VrfTables that holds the list of VrfEntries of the specified rd */ - public static VrfTables getVrfTable(DataBroker broker, String rd) { - InstanceIdentifier id = - InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)).build(); - Optional vrfTable = read(broker, LogicalDatastoreType.CONFIGURATION, id); + @Nullable + VrfTables getVrfTable(String rd) { + InstanceIdentifier id = InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, + new VrfTablesKey(rd)).build(); + Optional vrfTable = read(LogicalDatastoreType.CONFIGURATION, id); return vrfTable.isPresent() ? vrfTable.get() : null; } @@ -349,15 +392,13 @@ public final class VpnUtil { * Retrieves the VrfEntries that belong to a given VPN filtered out by * Origin, searching by its Route-Distinguisher. * - * @param broker dataBroker service reference * @param rd Route-distinguisher of the VPN * @param originsToConsider Only entries whose origin is included in this list will be considered * @return the list of VrfEntries */ - public static List getVrfEntriesByOrigin(DataBroker broker, String rd, - List originsToConsider) { + public List getVrfEntriesByOrigin(String rd, List originsToConsider) { List result = new ArrayList<>(); - List allVpnVrfEntries = getAllVrfEntries(broker, rd); + List allVpnVrfEntries = getAllVrfEntries(rd); for (VrfEntry vrfEntry : allVpnVrfEntries) { if (originsToConsider.contains(RouteOrigin.value(vrfEntry.getOrigin()))) { result.add(vrfEntry); @@ -366,71 +407,68 @@ public final class VpnUtil { return result; } - static List getAllPrefixesToInterface(DataBroker broker, long vpnId) { - Optional vpnIds = read(broker, LogicalDatastoreType.OPERATIONAL, getPrefixToInterfaceIdentifier(vpnId)); - if (vpnIds.isPresent()) { - return vpnIds.get().getPrefixes(); - } - return new ArrayList<>(); - } - /** * Retrieves all the VrfEntries that belong to a given VPN searching by its * Route-Distinguisher. * - * @param broker dataBroker service reference * @param rd Route-distinguisher of the VPN * @return the list of VrfEntries */ - public static List getAllVrfEntries(DataBroker broker, String rd) { - VrfTables vrfTables = VpnUtil.getVrfTable(broker, rd); - return vrfTables != null ? vrfTables.getVrfEntry() : new ArrayList<>(); + public List getAllVrfEntries(String rd) { + VrfTables vrfTables = getVrfTable(rd); + if (vrfTables != null && vrfTables.getVrfEntry() != null) { + return vrfTables.getVrfEntry(); + } + return emptyList(); } //FIXME: Implement caches for DS reads - public static VpnInstance getVpnInstance(DataBroker broker, String vpnInstanceName) { + @Nullable + public VpnInstance getVpnInstance(String vpnInstanceName) { InstanceIdentifier id = InstanceIdentifier.builder(VpnInstances.class).child(VpnInstance.class, new VpnInstanceKey(vpnInstanceName)).build(); - Optional vpnInstance = read(broker, LogicalDatastoreType.CONFIGURATION, id); + Optional vpnInstance = read(LogicalDatastoreType.CONFIGURATION, id); return vpnInstance.isPresent() ? vpnInstance.get() : null; } - public static List getAllVpnInstanceOpData(DataBroker broker) { + @Nonnull + List getAllVpnInstanceOpData() { InstanceIdentifier id = InstanceIdentifier.builder(VpnInstanceOpData.class).build(); - Optional vpnInstanceOpDataOptional = - VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, id); - if (vpnInstanceOpDataOptional.isPresent()) { - return vpnInstanceOpDataOptional.get().getVpnInstanceOpDataEntry(); - } else { - return new ArrayList<>(); - } + Optional vpnInstanceOpDataOptional = read(LogicalDatastoreType.OPERATIONAL, id); + return + vpnInstanceOpDataOptional.isPresent() && vpnInstanceOpDataOptional.get().getVpnInstanceOpDataEntry() != null + ? vpnInstanceOpDataOptional.get().getVpnInstanceOpDataEntry() + : emptyList(); } - public static List getDpnVpnInterfaces(DataBroker broker, - VpnInstance vpnInstance, BigInteger dpnId) { + @Nonnull + List getDpnVpnInterfaces(VpnInstance vpnInstance, + BigInteger dpnId) { String primaryRd = getPrimaryRd(vpnInstance); InstanceIdentifier dpnToVpnId = VpnHelper.getVpnToDpnListIdentifier(primaryRd, dpnId); - Optional dpnInVpn = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, dpnToVpnId); - return dpnInVpn.isPresent() ? dpnInVpn.get().getVpnInterfaces() : Collections.emptyList(); + Optional dpnInVpn = read(LogicalDatastoreType.OPERATIONAL, dpnToVpnId); + return dpnInVpn.isPresent() && dpnInVpn.get().getVpnInterfaces() != null ? dpnInVpn.get().getVpnInterfaces() + : emptyList(); } - public static List getListOfRdsFromVpnInstance(VpnInstance vpnInstance) { + @Nonnull + static List getListOfRdsFromVpnInstance(VpnInstance vpnInstance) { VpnAfConfig vpnConfig = vpnInstance.getIpv4Family(); LOG.trace("vpnConfig {}", vpnConfig); - return vpnConfig.getRouteDistinguisher() != null ? new ArrayList<>( - vpnConfig.getRouteDistinguisher()) : new ArrayList<>(); + return vpnConfig.getRouteDistinguisher() != null && vpnConfig.getRouteDistinguisher() != null + ? vpnConfig.getRouteDistinguisher() : emptyList(); } - static VrfEntry getVrfEntry(DataBroker broker, String rd, String ipPrefix) { - - VrfTables vrfTable = getVrfTable(broker, rd); + @Nullable + VrfEntry getVrfEntry(String rd, String ipPrefix) { + VrfTables vrfTable = getVrfTable(rd); // TODO: why check VrfTables if we later go for the specific VrfEntry? if (vrfTable != null) { InstanceIdentifier vrfEntryId = InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)).child( VrfEntry.class, new VrfEntryKey(ipPrefix)).build(); - Optional vrfEntry = read(broker, LogicalDatastoreType.CONFIGURATION, vrfEntryId); + Optional vrfEntry = read(LogicalDatastoreType.CONFIGURATION, vrfEntryId); if (vrfEntry.isPresent()) { return vrfEntry.get(); } @@ -438,30 +476,29 @@ public final class VpnUtil { return null; } - static List getAdjacenciesForVpnInterfaceFromConfig(DataBroker broker, String intfName) { + @Nullable + public List getAdjacenciesForVpnInterfaceFromConfig(String intfName) { final InstanceIdentifier identifier = getVpnInterfaceIdentifier(intfName); InstanceIdentifier path = identifier.augmentation(Adjacencies.class); - Optional adjacencies = VpnUtil.read(broker, LogicalDatastoreType.CONFIGURATION, path); - + Optional adjacencies = read(LogicalDatastoreType.CONFIGURATION, path); if (adjacencies.isPresent()) { - List nextHops = adjacencies.get().getAdjacency(); - return nextHops; + return adjacencies.get().getAdjacency(); } return null; } - static Routes getVpnToExtraroute(String ipPrefix, List nextHopList) { + static Routes getVpnToExtraroute(String ipPrefix, List nextHopList) { return new RoutesBuilder().setPrefix(ipPrefix).setNexthopIpList(nextHopList).build(); } - static String getVpnInterfaceName(OdlInterfaceRpcService odlInterfaceRpcService, BigInteger metadata) - throws InterruptedException, ExecutionException { + @Nullable + String getVpnInterfaceName(BigInteger metadata) throws InterruptedException, ExecutionException { GetInterfaceFromIfIndexInputBuilder ifIndexInputBuilder = new GetInterfaceFromIfIndexInputBuilder(); BigInteger lportTag = MetaDataUtil.getLportFromMetadata(metadata); ifIndexInputBuilder.setIfIndex(lportTag.intValue()); GetInterfaceFromIfIndexInput input = ifIndexInputBuilder.build(); Future> interfaceFromIfIndex = - odlInterfaceRpcService.getInterfaceFromIfIndex(input); + ifmRpcService.getInterfaceFromIfIndex(input); GetInterfaceFromIfIndexOutput interfaceFromIfIndexOutput; RpcResult rpcResult = interfaceFromIfIndex.get(); if (rpcResult == null) { @@ -472,10 +509,10 @@ public final class VpnUtil { } static AllocatedRdsBuilder getRdsBuilder(String nexthop, String rd) { - return new AllocatedRdsBuilder().setKey(new AllocatedRdsKey(nexthop)).setNexthop(nexthop).setRd(rd); + return new AllocatedRdsBuilder().withKey(new AllocatedRdsKey(nexthop)).setNexthop(nexthop).setRd(rd); } - static Adjacencies getVpnInterfaceAugmentation(List nextHopList) { + public static Adjacencies getVpnInterfaceAugmentation(List nextHopList) { return new AdjacenciesBuilder().setAdjacency(nextHopList).build(); } @@ -483,39 +520,17 @@ public final class VpnUtil { return new AdjacenciesOpBuilder().setAdjacency(nextHopList).build(); } - public static InstanceIdentifier getPoolId(String poolName) { - InstanceIdentifier.InstanceIdentifierBuilder idBuilder = - InstanceIdentifier.builder(IdPools.class).child(IdPool.class, new IdPoolKey(poolName)); - return idBuilder.build(); - } - - static InstanceIdentifier getVpnInterfacesIdentifier() { - return InstanceIdentifier.builder(VpnInterfaces.class).build(); - } - static InstanceIdentifier getInterfaceIdentifier(String interfaceName) { - return InstanceIdentifier.builder(Interfaces.class) - .child(Interface.class, new InterfaceKey(interfaceName)).build(); - } - - public static BigInteger getCookieArpFlow(int interfaceTag) { - return VpnConstants.COOKIE_L3_BASE.add(new BigInteger("0110000", 16)).add( - BigInteger.valueOf(interfaceTag)); + return InstanceIdentifier.builder(Interfaces.class).child(Interface.class, + new InterfaceKey(interfaceName)).build(); } public static BigInteger getCookieL3(int vpnId) { return VpnConstants.COOKIE_L3_BASE.add(new BigInteger("0610000", 16)).add(BigInteger.valueOf(vpnId)); } - public static String getFlowRef(BigInteger dpnId, short tableId, int ethType, int lportTag, int arpType) { - return new StringBuffer().append(VpnConstants.FLOWID_PREFIX).append(dpnId).append(NwConstants.FLOWID_SEPARATOR) - .append(tableId).append(NwConstants.FLOWID_SEPARATOR).append(ethType).append(lportTag) - .append(NwConstants.FLOWID_SEPARATOR).append(arpType).toString(); - } - - public static int getUniqueId(IdManagerService idManager, String poolName, String idKey) { + public int getUniqueId(String poolName, String idKey) { AllocateIdInput getIdInput = new AllocateIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build(); - try { Future> result = idManager.allocateId(getIdInput); RpcResult rpcResult = result.get(); @@ -531,7 +546,7 @@ public final class VpnUtil { return 0; } - public static void releaseId(IdManagerService idManager, String poolName, String idKey) { + void releaseId(String poolName, String idKey) { ReleaseIdInput idInput = new ReleaseIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build(); try { RpcResult rpcResult = idManager.releaseId(idInput).get(); @@ -548,63 +563,33 @@ public final class VpnUtil { return rd + VpnConstants.SEPARATOR + prefix; } - /** - * Retrieves the VpnInstance name (typically the VPN Uuid) out from the - * route-distinguisher. - * - * @param broker dataBroker service reference - * @param rd Route-Distinguisher - * @return the VpnInstance name - */ - public static String getVpnNameFromRd(DataBroker broker, String rd) { - VpnInstanceOpDataEntry vpnInstanceOpData = getVpnInstanceOpData(broker, rd); - return vpnInstanceOpData != null ? vpnInstanceOpData.getVpnInstanceName() : null; - } - /** * Retrieves the dataplane identifier of a specific VPN, searching by its * VpnInstance name. * - * @param broker dataBroker service reference * @param vpnName Name of the VPN * @return the dataplane identifier of the VPN, the VrfTag. */ - public static long getVpnId(DataBroker broker, String vpnName) { + public long getVpnId(String vpnName) { if (vpnName == null) { return VpnConstants.INVALID_ID; } - return read(broker, LogicalDatastoreType.CONFIGURATION, - VpnOperDsUtils.getVpnInstanceToVpnIdIdentifier(vpnName)).toJavaUtil().map( - org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id - .VpnInstance::getVpnId).orElse(VpnConstants.INVALID_ID); - } - - public static InstanceIdentifier 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(); + return read(LogicalDatastoreType.CONFIGURATION, VpnOperDsUtils.getVpnInstanceToVpnIdIdentifier(vpnName)) + .toJavaUtil().map(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911 + .vpn.instance.to.vpn.id.VpnInstance::getVpnId).orElse(VpnConstants.INVALID_ID); } /** * Retrieves the VPN Route Distinguisher searching by its Vpn instance name. * - * @param broker dataBroker service reference * @param vpnName Name of the VPN * @return the route-distinguisher of the VPN */ - public static String getVpnRd(DataBroker broker, String vpnName) { + public String getVpnRd(String vpnName) { Optional - vpnInstance - = read(broker, LogicalDatastoreType.CONFIGURATION, VpnOperDsUtils.getVpnInstanceToVpnIdIdentifier(vpnName)); - + .VpnInstance> vpnInstance = read(LogicalDatastoreType.CONFIGURATION, + VpnOperDsUtils.getVpnInstanceToVpnIdIdentifier(vpnName)); String rd = null; if (vpnInstance.isPresent()) { rd = vpnInstance.get().getVrfId(); @@ -612,68 +597,78 @@ public final class VpnUtil { return rd; } - private static List getVpnRdsFromVpnInstanceConfig(DataBroker broker, String vpnName) { + public static String getVpnRd(TypedReadTransaction confTx, String vpnName) { + try { + return confTx.read(VpnOperDsUtils.getVpnInstanceToVpnIdIdentifier(vpnName)).get().toJavaUtil().map( + vpnInstance -> vpnInstance.getVrfId()).orElse(null); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } + } + + List getVpnRdsFromVpnInstanceConfig(String vpnName) { InstanceIdentifier id = InstanceIdentifier.builder(VpnInstances.class) .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build(); - Optional vpnInstance = VpnUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id); + Optional vpnInstance = read(LogicalDatastoreType.CONFIGURATION, id); return vpnInstance.isPresent() ? getListOfRdsFromVpnInstance(vpnInstance.get()) : new ArrayList<>(); } /** * Remove from MDSAL all those VrfEntries in a VPN that have an specific RouteOrigin. * - * @param broker dataBroker service reference * @param rd Route Distinguisher * @param origin Origin of the Routes to be removed (see {@link RouteOrigin}) */ - public static void removeVrfEntriesByOrigin(DataBroker broker, String rd, RouteOrigin origin) { + public void removeVrfEntriesByOrigin(String rd, RouteOrigin origin) { InstanceIdentifier vpnVrfTableIid = InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)).build(); - Optional vrfTablesOpc = read(broker, LogicalDatastoreType.CONFIGURATION, vpnVrfTableIid); + Optional vrfTablesOpc = read(LogicalDatastoreType.CONFIGURATION, vpnVrfTableIid); if (vrfTablesOpc.isPresent()) { VrfTables vrfTables = vrfTablesOpc.get(); - WriteTransaction tx = broker.newWriteOnlyTransaction(); - for (VrfEntry vrfEntry : vrfTables.getVrfEntry()) { - if (origin == RouteOrigin.value(vrfEntry.getOrigin())) { - tx.delete(LogicalDatastoreType.CONFIGURATION, - vpnVrfTableIid.child(VrfEntry.class, vrfEntry.getKey())); - } - } - tx.submit(); + ListenableFutures.addErrorLogging( + new ManagedNewTransactionRunnerImpl(dataBroker).callWithNewWriteOnlyTransactionAndSubmit( + Datastore.CONFIGURATION, tx -> { + for (VrfEntry vrfEntry : requireNonNullElse(vrfTables.getVrfEntry(), + Collections.emptyList())) { + if (origin == RouteOrigin.value(vrfEntry.getOrigin())) { + tx.delete(vpnVrfTableIid.child(VrfEntry.class, vrfEntry.key())); + } + } + }), LOG, "Error removing VRF entries by origin"); } } - public static List findVrfEntriesByNexthop(DataBroker broker, String rd, String nexthop) { + public List findVrfEntriesByNexthop(String rd, String nexthop) { InstanceIdentifier vpnVrfTableIid = InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)).build(); - Optional vrfTablesOpc = read(broker, LogicalDatastoreType.CONFIGURATION, vpnVrfTableIid); + Optional vrfTablesOpc = read(LogicalDatastoreType.CONFIGURATION, vpnVrfTableIid); List matches = new ArrayList<>(); - if (vrfTablesOpc.isPresent()) { VrfTables vrfTables = vrfTablesOpc.get(); - for (VrfEntry vrfEntry : vrfTables.getVrfEntry()) { - vrfEntry.getRoutePaths().stream() - .filter(routePath -> routePath.getNexthopAddress() != null - && routePath.getNexthopAddress().equals(nexthop)) - .findFirst().ifPresent(routePath -> matches.add(vrfEntry)); + for (VrfEntry vrfEntry : requireNonNullElse(vrfTables.getVrfEntry(), Collections.emptyList())) { + requireNonNullElse(vrfEntry.getRoutePaths(), Collections.emptyList()).stream() + .filter(routePath -> routePath.getNexthopAddress() != null && routePath.getNexthopAddress() + .equals(nexthop)).findFirst().ifPresent(routePath -> matches.add(vrfEntry)); } } return matches; } - public static void removeVrfEntries(DataBroker broker, String rd, List vrfEntries) { + public void removeVrfEntries(String rd, List vrfEntries) { InstanceIdentifier vpnVrfTableIid = InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)).build(); - WriteTransaction tx = broker.newWriteOnlyTransaction(); - for (VrfEntry vrfEntry : vrfEntries) { - tx.delete(LogicalDatastoreType.CONFIGURATION, vpnVrfTableIid.child(VrfEntry.class, vrfEntry.getKey())); - } - tx.submit(); + ListenableFutures.addErrorLogging( + new ManagedNewTransactionRunnerImpl(dataBroker).callWithNewWriteOnlyTransactionAndSubmit( + Datastore.CONFIGURATION, tx -> { + for (VrfEntry vrfEntry : vrfEntries) { + tx.delete(vpnVrfTableIid.child(VrfEntry.class, vrfEntry.key())); + } + }), LOG, "Error removing VRF entries"); } // TODO Clean up the exception handling @SuppressWarnings("checkstyle:IllegalCatch") - public static void withdrawRoutes(IBgpManager bgpManager, String rd, List vrfEntries) { + public void withdrawRoutes(String rd, List vrfEntries) { vrfEntries.forEach(vrfEntry -> { try { bgpManager.withdrawPrefix(rd, vrfEntry.getDestPrefix()); @@ -684,36 +679,56 @@ public final class VpnUtil { }); } + public boolean removeOrUpdateDSForExtraRoute(String vpnName, String primaryRd, String extraRouteRd, + String vpnInterfaceName, String prefix, String nextHop, + String nextHopTunnelIp, TypedWriteTransaction operTx) { + LOG.info("removeOrUpdateDSForExtraRoute: VPN WITHDRAW: Removing Fib Entry rd {} prefix {} nexthop {}", + extraRouteRd, prefix, nextHop); + boolean areNextHopsClearedForRd = false; + Optional optVpnExtraRoutes = VpnExtraRouteHelper + .getVpnExtraroutes(dataBroker, vpnName, extraRouteRd, prefix); + if (optVpnExtraRoutes.isPresent()) { + List nhList = optVpnExtraRoutes.get().getNexthopIpList(); + if (nhList != null && nhList.size() > 1) { + // If nhList is more than 1, just update vpntoextraroute and prefixtointerface DS + // For other cases, remove the corresponding tep ip from fibentry and withdraw prefix + nhList.remove(nextHop); + syncWrite(LogicalDatastoreType.OPERATIONAL, + VpnExtraRouteHelper.getVpnToExtrarouteVrfIdIdentifier(vpnName, extraRouteRd, prefix), + VpnUtil.getVpnToExtraroute(prefix, nhList)); + MDSALUtil.syncDelete(dataBroker, + LogicalDatastoreType.CONFIGURATION, VpnExtraRouteHelper.getUsedRdsIdentifier(getVpnId(vpnName), + prefix, nextHop)); + LOG.debug("removeOrUpdateDSForExtraRoute: Removed vpn-to-extraroute with rd {} prefix {} nexthop {}", + extraRouteRd, prefix, nextHop); + fibManager.refreshVrfEntry(primaryRd, prefix); + operTx.delete(VpnUtil.getVpnInterfaceOpDataEntryAdjacencyIdentifier(vpnInterfaceName, vpnName, prefix)); + LOG.info("VPN WITHDRAW: removeOrUpdateDSForExtraRoute: Removed Fib Entry rd {} prefix {} nexthop {}", + extraRouteRd, prefix, nextHopTunnelIp); + areNextHopsClearedForRd = true; + } + } + return areNextHopsClearedForRd; + } + static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance getVpnInstanceToVpnId(String vpnName, long vpnId, String rd) { return new VpnInstanceBuilder().setVpnId(vpnId).setVpnInstanceName(vpnName).setVrfId(rd).build(); } - static RouterInterface getConfiguredRouterInterface(DataBroker broker, String interfaceName) { - Optional optRouterInterface = - read(broker, LogicalDatastoreType.CONFIGURATION, VpnUtil.getRouterInterfaceId(interfaceName)); - if (optRouterInterface.isPresent()) { - return optRouterInterface.get(); - } - return null; - } - static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds getVpnIdToVpnInstance(long vpnId, String vpnName, String rd, boolean isExternalVpn) { return new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance - .VpnIdsBuilder() - .setVpnId(vpnId).setVpnInstanceName(vpnName).setVrfId(rd).setExternalVpn(isExternalVpn).build(); + .VpnIdsBuilder().setVpnId(vpnId).setVpnInstanceName(vpnName).setVrfId(rd).setExternalVpn(isExternalVpn) + .build(); } - public static InstanceIdentifier - getVpnIdToVpnInstanceIdentifier(long vpnId) { - return InstanceIdentifier.builder(VpnIdToVpnInstance.class) - .child( - org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds - .class, + static InstanceIdentifier getVpnIdToVpnInstanceIdentifier(long vpnId) { + return InstanceIdentifier.builder(VpnIdToVpnInstance.class).child(org.opendaylight.yang.gen.v1.urn + .opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance .VpnIdsKey(vpnId)).build(); } @@ -721,20 +736,17 @@ public final class VpnUtil { /** * Retrieves the Vpn Name searching by its VPN Tag. * - * @param broker dataBroker service reference * @param vpnId Dataplane identifier of the VPN * @return the Vpn instance name */ - public static String getVpnName(DataBroker broker, long vpnId) { + @Nullable + String getVpnName(long vpnId) { InstanceIdentifier - id - = getVpnIdToVpnInstanceIdentifier(vpnId); + .instance.VpnIds> id = getVpnIdToVpnInstanceIdentifier(vpnId); Optional vpnInstance - = read(broker, LogicalDatastoreType.CONFIGURATION, id); - + = read(LogicalDatastoreType.CONFIGURATION, id); String vpnName = null; if (vpnInstance.isPresent()) { vpnName = vpnInstance.get().getVpnInstanceName(); @@ -747,67 +759,30 @@ public final class VpnUtil { .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(rd)).build(); } - static InstanceIdentifier getRouterInterfaceId(String interfaceName) { - return InstanceIdentifier.builder(RouterInterfaces.class) - .child(RouterInterface.class, new RouterInterfaceKey(interfaceName)).build(); + @Nullable + public VpnInstanceOpDataEntry getVpnInstanceOpData(String rd) { + return read(LogicalDatastoreType.OPERATIONAL, getVpnInstanceOpDataIdentifier(rd)).orNull(); } - static RouterInterface getRouterInterface(String interfaceName, String routerName) { - return new RouterInterfaceBuilder().setKey(new RouterInterfaceKey(interfaceName)) - .setInterfaceName(interfaceName).setRouterName(routerName).build(); - } - - public static VpnInstanceOpDataEntry getVpnInstanceOpData(DataBroker broker, String rd) { - InstanceIdentifier id = VpnUtil.getVpnInstanceOpDataIdentifier(rd); - return read(broker, LogicalDatastoreType.OPERATIONAL, id).orNull(); - } - - static VpnInterface getConfiguredVpnInterface(DataBroker broker, String interfaceName) { + @Nullable + VpnInterface getConfiguredVpnInterface(String interfaceName) { InstanceIdentifier interfaceId = getVpnInterfaceIdentifier(interfaceName); - Optional configuredVpnInterface = read(broker, LogicalDatastoreType.CONFIGURATION, interfaceId); - + Optional configuredVpnInterface = read(LogicalDatastoreType.CONFIGURATION, interfaceId); if (configuredVpnInterface.isPresent()) { return configuredVpnInterface.get(); } return null; } - static String getNeutronRouterFromInterface(DataBroker broker, String interfaceName) { - InstanceIdentifier.InstanceIdentifierBuilder idBuilder = - InstanceIdentifier.builder(RouterInterfacesMap.class); - InstanceIdentifier id = idBuilder.build(); - Optional routerInterfacesMap = - MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id); - if (routerInterfacesMap.isPresent()) { - List - rtrInterfaces = routerInterfacesMap.get().getRouterInterfaces(); - for (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map - .RouterInterfaces rtrInterface : rtrInterfaces) { - List - rtrIfc = rtrInterface.getInterfaces(); - for (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map - .router.interfaces.Interfaces ifc : rtrIfc) { - if (ifc.getInterfaceId().equals(interfaceName)) { - return rtrInterface.getRouterId().getValue(); - } - } - } - } - return null; - } - - static boolean isVpnInterfaceConfigured(DataBroker broker, String interfaceName) { + boolean isVpnInterfaceConfigured(String interfaceName) { InstanceIdentifier interfaceId = getVpnInterfaceIdentifier(interfaceName); - return read(broker, LogicalDatastoreType.CONFIGURATION, interfaceId).isPresent(); + return read(LogicalDatastoreType.CONFIGURATION, interfaceId).isPresent(); } - static Optional> getVpnHandlingIpv4AssociatedWithInterface(DataBroker broker, String interfaceName) { + public Optional> getVpnHandlingIpv4AssociatedWithInterface(String interfaceName) { InstanceIdentifier interfaceId = getVpnInterfaceIdentifier(interfaceName); Optional> vpnOptional = Optional.absent(); - Optional optConfiguredVpnInterface = read(broker, LogicalDatastoreType.CONFIGURATION, - interfaceId); + Optional optConfiguredVpnInterface = read(LogicalDatastoreType.CONFIGURATION, interfaceId); if (optConfiguredVpnInterface.isPresent()) { VpnInterface cfgVpnInterface = optConfiguredVpnInterface.get(); java.util.Optional> optVpnInstanceList = @@ -815,9 +790,6 @@ public final class VpnUtil { if (optVpnInstanceList.isPresent()) { List vpnList = new ArrayList<>(); for (VpnInstanceNames vpnInstance : optVpnInstanceList.get()) { - if (vpnInstance.getAssociatedSubnetType().equals(AssociatedSubnetType.V6Subnet)) { - continue; - } vpnList.add(vpnInstance.getVpnName()); } vpnOptional = Optional.of(vpnList); @@ -827,11 +799,7 @@ public final class VpnUtil { } public static String getIpPrefix(String prefix) { - String[] prefixValues = prefix.split("/"); - if (prefixValues.length == 1) { - prefix = prefix + PREFIX_SEPARATOR + DEFAULT_PREFIX_LENGTH; - } - return prefix; + return prefix.indexOf('/') != -1 ? prefix : NWUtil.toIpPrefix(prefix); } static final FutureCallback DEFAULT_CALLBACK = @@ -848,352 +816,185 @@ public final class VpnUtil { }; - public static Optional read(DataBroker broker, LogicalDatastoreType datastoreType, - InstanceIdentifier path) { - try (ReadOnlyTransaction tx = broker.newReadOnlyTransaction()) { - return tx.read(datastoreType, path).get(); - } catch (InterruptedException | ExecutionException e) { - throw new RuntimeException(e); - } - } - - public static void asyncUpdate(DataBroker broker, LogicalDatastoreType datastoreType, - InstanceIdentifier path, T data) { - asyncUpdate(broker, datastoreType, path, data, DEFAULT_CALLBACK); - } - - public static void asyncUpdate(DataBroker broker, LogicalDatastoreType datastoreType, - InstanceIdentifier path, T data, FutureCallback callback) { - WriteTransaction tx = broker.newWriteOnlyTransaction(); - tx.merge(datastoreType, path, data, true); - Futures.addCallback(tx.submit(), callback, MoreExecutors.directExecutor()); - } - - public static void asyncWrite(DataBroker broker, LogicalDatastoreType datastoreType, - InstanceIdentifier path, T data) { - asyncWrite(broker, datastoreType, path, data, DEFAULT_CALLBACK); - } - - public static void asyncWrite(DataBroker broker, LogicalDatastoreType datastoreType, - InstanceIdentifier path, T data, FutureCallback callback) { - WriteTransaction tx = broker.newWriteOnlyTransaction(); - tx.put(datastoreType, path, data, WriteTransaction.CREATE_MISSING_PARENTS); - Futures.addCallback(tx.submit(), callback, MoreExecutors.directExecutor()); - } - - // TODO Clean up the exception handling - @SuppressWarnings("checkstyle:IllegalCatch") - public static void tryDelete(DataBroker broker, LogicalDatastoreType datastoreType, - InstanceIdentifier path) { + @Deprecated + private Optional read(LogicalDatastoreType datastoreType, InstanceIdentifier path) { try { - delete(broker, datastoreType, path, DEFAULT_CALLBACK); - } catch (SchemaValidationFailedException sve) { - LOG.info("tryDelete: Could not delete {}. SchemaValidationFailedException: {}", path, sve.getMessage()); - } catch (Exception e) { - LOG.info("tryDelete: Could not delete {}. Unhandled error: {}", path, e.getMessage()); + return SingleTransactionDataBroker.syncReadOptional(dataBroker, datastoreType, path); + } catch (ReadFailedException e) { + throw new RuntimeException(e); } } - public static void delete(DataBroker broker, LogicalDatastoreType datastoreType, - InstanceIdentifier path) { - delete(broker, datastoreType, path, DEFAULT_CALLBACK); - } - - - public static void delete(DataBroker broker, LogicalDatastoreType datastoreType, - InstanceIdentifier path, FutureCallback callback) { - WriteTransaction tx = broker.newWriteOnlyTransaction(); - tx.delete(datastoreType, path); - Futures.addCallback(tx.submit(), callback, MoreExecutors.directExecutor()); - } - - public static void syncWrite(DataBroker broker, LogicalDatastoreType datastoreType, - InstanceIdentifier path, T data) { - WriteTransaction tx = broker.newWriteOnlyTransaction(); - tx.put(datastoreType, path, data, WriteTransaction.CREATE_MISSING_PARENTS); - + @Deprecated + public void syncWrite(LogicalDatastoreType datastoreType, InstanceIdentifier path, + T data) { try { - tx.submit().get(); - } catch (InterruptedException | ExecutionException e) { - LOG.error("syncWrite: Error writing to datastore (path, data) : ({}, {})", path, data); + SingleTransactionDataBroker.syncWrite(dataBroker, datastoreType, path, data); + } catch (TransactionCommitFailedException e) { + LOG.error("syncWrite: Error writing to datastore (path, data) : ({}, {})", path, data, e); throw new RuntimeException(e.getMessage(), e); } } - public static void syncUpdate(DataBroker broker, LogicalDatastoreType datastoreType, - InstanceIdentifier path, T data) { - WriteTransaction tx = broker.newWriteOnlyTransaction(); - tx.merge(datastoreType, path, data, true); - + @Deprecated + public void syncUpdate(LogicalDatastoreType datastoreType, InstanceIdentifier path, + T data) { try { - tx.submit().get(); - } catch (InterruptedException | ExecutionException e) { - LOG.error("syncUpdate: Error writing to datastore (path, data) : ({}, {})", path, data); + SingleTransactionDataBroker.syncUpdate(dataBroker, datastoreType, path, data); + } catch (TransactionCommitFailedException e) { + LOG.error("syncUpdate: Error writing to datastore (path, data) : ({}, {})", path, data, e); throw new RuntimeException(e.getMessage(), e); } } - public static long getRemoteBCGroup(long elanTag) { + static long getRemoteBCGroup(long elanTag) { return VpnConstants.ELAN_GID_MIN + elanTag % VpnConstants.ELAN_GID_MIN * 2; } // interface-index-tag operational container - public static IfIndexInterface getInterfaceInfoByInterfaceTag(DataBroker broker, long interfaceTag) { + @Nullable + IfIndexInterface getInterfaceInfoByInterfaceTag(long interfaceTag) { InstanceIdentifier interfaceId = getInterfaceInfoEntriesOperationalDataPath(interfaceTag); - Optional existingInterfaceInfo = - VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, interfaceId); + Optional existingInterfaceInfo = read(LogicalDatastoreType.OPERATIONAL, interfaceId); if (existingInterfaceInfo.isPresent()) { return existingInterfaceInfo.get(); } return null; } - private static InstanceIdentifier getInterfaceInfoEntriesOperationalDataPath(long interfaceTag) { + static InstanceIdentifier getInterfaceInfoEntriesOperationalDataPath(long interfaceTag) { return InstanceIdentifier.builder(IfIndexesInterfaceMap.class).child(IfIndexInterface.class, new IfIndexInterfaceKey((int) interfaceTag)).build(); } - public static ElanTagName getElanInfoByElanTag(DataBroker broker, long elanTag) { + @Nullable + ElanTagName getElanInfoByElanTag(long elanTag) { InstanceIdentifier elanId = getElanInfoEntriesOperationalDataPath(elanTag); - Optional existingElanInfo = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, elanId); + Optional existingElanInfo = read(LogicalDatastoreType.OPERATIONAL, elanId); if (existingElanInfo.isPresent()) { return existingElanInfo.get(); } return null; } - private static InstanceIdentifier getElanInfoEntriesOperationalDataPath(long elanTag) { + static InstanceIdentifier getElanInfoEntriesOperationalDataPath(long elanTag) { return InstanceIdentifier.builder(ElanTagNameMap.class).child(ElanTagName.class, new ElanTagNameKey(elanTag)).build(); } - /** - * Returns the Path identifier to reach a specific interface in a specific DPN in a given VpnInstance. - * - * @param vpnRd Route-Distinguisher of the VpnInstance - * @param dpnId Id of the DPN where the interface is - * @param ifaceName Interface name - * @return the Instance Identifier - */ - public static InstanceIdentifier - getVpnToDpnInterfacePath(String vpnRd, BigInteger dpnId, String ifaceName) { - - return - InstanceIdentifier.builder(VpnInstanceOpData.class) - .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vpnRd)) - .child(VpnToDpnList.class, new VpnToDpnListKey(dpnId)) - .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn - .instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces.class, - new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn - .instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfacesKey(ifaceName)) - .build(); + static void removePrefixToInterfaceForVpnId(long vpnId, @Nonnull TypedWriteTransaction operTx) { + // Clean up PrefixToInterface Operational DS + operTx.delete(InstanceIdentifier.builder( + PrefixToInterface.class).child(VpnIds.class, new VpnIdsKey(vpnId)).build()); } - // TODO Clean up the exception handling - @SuppressWarnings("checkstyle:IllegalCatch") - public static void removePrefixToInterfaceForVpnId(DataBroker broker, long vpnId, WriteTransaction writeTxn) { - try { - // Clean up PrefixToInterface Operational DS - if (writeTxn != null) { - writeTxn.delete(LogicalDatastoreType.OPERATIONAL, - InstanceIdentifier.builder(PrefixToInterface.class).child( - VpnIds.class, new VpnIdsKey(vpnId)).build()); - } else { - delete(broker, LogicalDatastoreType.OPERATIONAL, - InstanceIdentifier.builder(PrefixToInterface.class).child(VpnIds.class, - new VpnIdsKey(vpnId)).build(), - DEFAULT_CALLBACK); - } - } catch (Exception e) { - LOG.error("removePrefixToInterfaceForVpnId: Exception during cleanup of PrefixToInterface for VPN ID {}", - vpnId, e); - } + static void removeVpnExtraRouteForVpn(String vpnName, @Nonnull TypedWriteTransaction operTx) { + // Clean up VPNExtraRoutes Operational DS + operTx.delete(InstanceIdentifier.builder(VpnToExtraroutes.class).child(Vpn.class, new VpnKey(vpnName)).build()); } - // TODO Clean up the exception handling @SuppressWarnings("checkstyle:IllegalCatch") - public static void removeVpnExtraRouteForVpn(DataBroker broker, String vpnName, WriteTransaction writeTxn) { - try { - // Clean up VPNExtraRoutes Operational DS - if (writeTxn != null) { - writeTxn.delete(LogicalDatastoreType.OPERATIONAL, - InstanceIdentifier.builder(VpnToExtraroutes.class) - .child(Vpn.class, new VpnKey(vpnName)).build()); - } else { - delete(broker, LogicalDatastoreType.OPERATIONAL, - InstanceIdentifier.builder(VpnToExtraroutes.class) - .child(Vpn.class, new VpnKey(vpnName)).build(), - DEFAULT_CALLBACK); - } - } catch (Exception e) { - LOG.error("removeVpnExtraRouteForVpna: Exception during cleanup of VPNToExtraRoute for VPN {}", - vpnName, e); - } + static void removeVpnOpInstance(String vpnName, @Nonnull TypedWriteTransaction operTx) { + // Clean up VPNInstanceOpDataEntry + operTx.delete(getVpnInstanceOpDataIdentifier(vpnName)); } - // TODO Clean up the exception handling - @SuppressWarnings("checkstyle:IllegalCatch") - public static void removeVpnOpInstance(DataBroker broker, String vpnName, WriteTransaction writeTxn) { - try { - // Clean up VPNInstanceOpDataEntry - if (writeTxn != null) { - writeTxn.delete(LogicalDatastoreType.OPERATIONAL, getVpnInstanceOpDataIdentifier(vpnName)); - } else { - delete(broker, LogicalDatastoreType.OPERATIONAL, getVpnInstanceOpDataIdentifier(vpnName), - DEFAULT_CALLBACK); - } - } catch (Exception e) { - LOG.error("removeVpnOpInstance: Exception during cleanup of VPNInstanceOpDataEntry for VPN {}", - vpnName, e); - } + static void removeVpnInstanceToVpnId(String vpnName, @Nonnull TypedWriteTransaction confTx) { + confTx.delete(VpnOperDsUtils.getVpnInstanceToVpnIdIdentifier(vpnName)); } - // TODO Clean up the exception handling - @SuppressWarnings("checkstyle:IllegalCatch") - public static void removeVpnInstanceToVpnId(DataBroker broker, String vpnName, WriteTransaction writeTxn) { - try { - if (writeTxn != null) { - writeTxn.delete(LogicalDatastoreType.CONFIGURATION, - VpnOperDsUtils.getVpnInstanceToVpnIdIdentifier(vpnName)); - } else { - delete(broker, LogicalDatastoreType.CONFIGURATION, - VpnOperDsUtils.getVpnInstanceToVpnIdIdentifier(vpnName), - DEFAULT_CALLBACK); - } - } catch (Exception e) { - LOG.error("removeVpnInstanceToVpnId: Exception during clean up of VpnInstanceToVpnId for VPN {}", - vpnName, e); - } + static void removeVpnIdToVpnInstance(long vpnId, @Nonnull TypedWriteTransaction confTx) { + confTx.delete(getVpnIdToVpnInstanceIdentifier(vpnId)); } - // TODO Clean up the exception handling - @SuppressWarnings("checkstyle:IllegalCatch") - public static void removeVpnIdToVpnInstance(DataBroker broker, long vpnId, WriteTransaction writeTxn) { - try { - if (writeTxn != null) { - writeTxn.delete(LogicalDatastoreType.CONFIGURATION, getVpnIdToVpnInstanceIdentifier(vpnId)); - } else { - delete(broker, LogicalDatastoreType.CONFIGURATION, getVpnIdToVpnInstanceIdentifier(vpnId), - DEFAULT_CALLBACK); - } - } catch (Exception e) { - LOG.error("removeVpnIdToVpnInstance: Exception during clean up of VpnIdToVpnInstance for VPNID {}", - vpnId, e); - } + static void removeL3nexthopForVpnId(long vpnId, @Nonnull TypedWriteTransaction operTx) { + // Clean up L3NextHop Operational DS + operTx.delete(InstanceIdentifier.builder(L3nexthop.class).child( + VpnNexthops.class, new VpnNexthopsKey(vpnId)).build()); } - // TODO Clean up the exception handling - @SuppressWarnings("checkstyle:IllegalCatch") - public static void removeVrfTableForVpn(DataBroker broker, String vpnName, WriteTransaction writeTxn) { - // Clean up FIB Entries Config DS - try { - if (writeTxn != null) { - writeTxn.delete(LogicalDatastoreType.CONFIGURATION, - InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, - new VrfTablesKey(vpnName)).build()); - } else { - delete(broker, LogicalDatastoreType.CONFIGURATION, - InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, - new VrfTablesKey(vpnName)).build(), - DEFAULT_CALLBACK); - } - } catch (Exception e) { - LOG.error("removeVrfTableForVpn: Exception during clean up of VrfTable from FIB for VPN {}", - vpnName, e); - } - } - - // TODO Clean up the exception handling - @SuppressWarnings("checkstyle:IllegalCatch") - public static void removeL3nexthopForVpnId(DataBroker broker, long vpnId, WriteTransaction writeTxn) { - try { - // Clean up L3NextHop Operational DS - if (writeTxn != null) { - writeTxn.delete(LogicalDatastoreType.OPERATIONAL, - InstanceIdentifier.builder(L3nexthop.class).child(VpnNexthops.class, - new VpnNexthopsKey(vpnId)).build()); - } else { - delete(broker, LogicalDatastoreType.OPERATIONAL, - InstanceIdentifier.builder(L3nexthop.class).child(VpnNexthops.class, - new VpnNexthopsKey(vpnId)).build(), - DEFAULT_CALLBACK); - } - } catch (Exception e) { - LOG.error("removeL3nexthopForVpnId: Exception during cleanup of L3NextHop for VPN ID {}", vpnId, e); - } - } - - public static void scheduleVpnInterfaceForRemoval(DataBroker broker,String interfaceName, BigInteger dpnId, - String vpnInstanceName, Boolean isScheduledToRemove, - WriteTransaction writeOperTxn) { + void scheduleVpnInterfaceForRemoval(String interfaceName, BigInteger dpnId, String vpnInstanceName, + @Nullable TypedWriteTransaction writeOperTxn) { InstanceIdentifier interfaceId = - VpnUtil.getVpnInterfaceOpDataEntryIdentifier(interfaceName, vpnInstanceName); + getVpnInterfaceOpDataEntryIdentifier(interfaceName, vpnInstanceName); VpnInterfaceOpDataEntry interfaceToUpdate = - new VpnInterfaceOpDataEntryBuilder().setKey(new VpnInterfaceOpDataEntryKey(interfaceName, + new VpnInterfaceOpDataEntryBuilder().withKey(new VpnInterfaceOpDataEntryKey(interfaceName, vpnInstanceName)).setName(interfaceName).setDpnId(dpnId).setVpnInstanceName(vpnInstanceName) - .setScheduledForRemove(isScheduledToRemove).build(); + .build(); if (writeOperTxn != null) { - writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL, interfaceId, interfaceToUpdate, true); + writeOperTxn.merge(interfaceId, interfaceToUpdate, true); } else { - VpnUtil.syncUpdate(broker, LogicalDatastoreType.OPERATIONAL, interfaceId, interfaceToUpdate); + syncUpdate(LogicalDatastoreType.OPERATIONAL, interfaceId, interfaceToUpdate); } } - protected static void createLearntVpnVipToPort(DataBroker broker, String vpnName, String fixedIp, String - portName, String macAddress, WriteTransaction writeOperTxn) { + public void createLearntVpnVipToPort(String vpnName, String fixedIp, String portName, String macAddress, + TypedWriteTransaction writeOperTxn) { synchronized ((vpnName + fixedIp).intern()) { InstanceIdentifier id = buildLearntVpnVipToPortIdentifier(vpnName, fixedIp); LearntVpnVipToPortBuilder builder = - new LearntVpnVipToPortBuilder().setKey(new LearntVpnVipToPortKey(fixedIp, vpnName)).setVpnName( + new LearntVpnVipToPortBuilder().withKey(new LearntVpnVipToPortKey(fixedIp, vpnName)).setVpnName( vpnName).setPortFixedip(fixedIp).setPortName(portName) .setMacAddress(macAddress.toLowerCase(Locale.getDefault())) .setCreationTime(new SimpleDateFormat("MM/dd/yyyy h:mm:ss a").format(new Date())); if (writeOperTxn != null) { - writeOperTxn.put(LogicalDatastoreType.OPERATIONAL, id, builder.build(), true); + writeOperTxn.put(id, builder.build(), true); } else { - MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, id, builder.build()); + syncWrite(LogicalDatastoreType.OPERATIONAL, id, builder.build()); } - LOG.debug("createLearntVpnVipToPort: ARP learned for fixedIp: {}, vpn {}, interface {}, mac {}," - + " added to VpnPortipToPort DS", fixedIp, vpnName, portName, macAddress); + LOG.debug("createLearntVpnVipToPort: ARP/NA learned for fixedIp: {}, vpn {}, interface {}, mac {}," + + " added to LearntVpnVipToPort DS", fixedIp, vpnName, portName, macAddress); } } - private static InstanceIdentifier buildLearntVpnVipToPortIdentifier(String vpnName, + static InstanceIdentifier buildLearntVpnVipToPortIdentifier(String vpnName, String fixedIp) { return InstanceIdentifier.builder(LearntVpnVipToPortData.class).child(LearntVpnVipToPort.class, new LearntVpnVipToPortKey(fixedIp, vpnName)).build(); } - protected static void removeLearntVpnVipToPort(DataBroker broker, String vpnName, String fixedIp, - WriteTransaction writeOperTxn) { + void removeLearntVpnVipToPort(String vpnName, String fixedIp, + @Nullable TypedWriteTransaction writeOperTxn) { synchronized ((vpnName + fixedIp).intern()) { InstanceIdentifier id = buildLearntVpnVipToPortIdentifier(vpnName, fixedIp); if (writeOperTxn != null) { - writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, id); + writeOperTxn.delete(id); } else { - MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, id); + MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.OPERATIONAL, id); } - LOG.debug("removeLearntVpnVipToPort: Delete learned ARP for fixedIp: {}, vpn {} removed from" - + " VpnPortipToPort DS", fixedIp, vpnName); + LOG.debug("removeLearntVpnVipToPort: Deleted LearntVpnVipToPort entry for fixedIp: {}, vpn {}", + fixedIp, vpnName); } } - protected static void createLearntVpnVipToPortEvent(DataBroker broker, String vpnName, String srcIp, String destIP, - String portName, String macAddress, - LearntVpnVipToPortEventAction action, - WriteTransaction writeOperTxn) { + protected static void removeVpnPortFixedIpToPort(DataBroker broker, String vpnName, String fixedIp, + @Nullable TypedWriteTransaction writeConfigTxn) { + synchronized ((vpnName + fixedIp).intern()) { + InstanceIdentifier id = buildVpnPortipToPortIdentifier(vpnName, fixedIp); + if (writeConfigTxn != null) { + writeConfigTxn.delete(id); + } else { + MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, id); + } + LOG.debug("removeVpnPortFixedIpToPort: Deleted VpnPortipToPort entry for fixedIp: {}, vpn {}", + fixedIp, vpnName); + } + } + + public void createLearntVpnVipToPortEvent(String vpnName, String srcIp, String destIP, String portName, + String macAddress, LearntVpnVipToPortEventAction action, + TypedWriteTransaction writeOperTxn) { String eventId = MicroTimestamp.INSTANCE.get(); InstanceIdentifier id = buildLearntVpnVipToPortEventIdentifier(eventId); - LearntVpnVipToPortEventBuilder builder = new LearntVpnVipToPortEventBuilder().setKey( + LearntVpnVipToPortEventBuilder builder = new LearntVpnVipToPortEventBuilder().withKey( new LearntVpnVipToPortEventKey(eventId)).setVpnName(vpnName).setSrcFixedip(srcIp) .setDestFixedip(destIP).setPortName(portName) .setMacAddress(macAddress.toLowerCase(Locale.getDefault())).setEventAction(action); if (writeOperTxn != null) { - writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, id); + writeOperTxn.delete(id); } else { - MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, id, builder.build()); + syncWrite(LogicalDatastoreType.OPERATIONAL, id, builder.build()); } LOG.info("createLearntVpnVipToPortEvent: ARP learn event created for fixedIp: {}, vpn {}, interface {}," + " mac {} action {} eventId {}", srcIp, vpnName, portName, macAddress, action, eventId); @@ -1205,39 +1006,19 @@ public final class VpnUtil { return id; } - protected static void removeLearntVpnVipToPortEvent(DataBroker broker, String eventId, - WriteTransaction writeOperTxn) { + public void removeLearntVpnVipToPortEvent(String eventId, + @Nullable TypedWriteTransaction writeOperTxn) { InstanceIdentifier id = buildLearntVpnVipToPortEventIdentifier(eventId); if (writeOperTxn != null) { - writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, id); + writeOperTxn.delete(id); } else { - MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, id); + MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.OPERATIONAL, id); } LOG.info("removeLearntVpnVipToPortEvent: Deleted Event {}", eventId); } - public static void removeMipAdjacency(DataBroker dataBroker, String vpnName, String vpnInterface, String prefix, - WriteTransaction writeConfigTxn) { - String ip = VpnUtil.getIpPrefix(prefix); - LOG.trace("Removing {} adjacency from Old VPN Interface {} ", ip, vpnInterface); - InstanceIdentifier vpnIfId = VpnUtil.getVpnInterfaceIdentifier(vpnInterface); - InstanceIdentifier path = vpnIfId.augmentation(Adjacencies.class); - //TODO: Remove synchronized? - - Optional adjacencies = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, path); - if (adjacencies.isPresent()) { - InstanceIdentifier adjacencyIdentifier = InstanceIdentifier.builder(VpnInterfaces.class) - .child(VpnInterface.class, new VpnInterfaceKey(vpnInterface)).augmentation(Adjacencies.class) - .child(Adjacency.class, new AdjacencyKey(ip)).build(); - writeConfigTxn.delete(LogicalDatastoreType.CONFIGURATION, adjacencyIdentifier); - LOG.error("removeMipAdjacency: Successfully Deleted Adjacency {} from interface {} vpn {}", ip, - vpnInterface, vpnName); - } - } - - public static void removeMipAdjAndLearntIp(DataBroker dataBroker, String vpnName, - String vpnInterface, String prefix) { + public void removeMipAdjAndLearntIp(String vpnName, String vpnInterface, String prefix) { synchronized ((vpnName + prefix).intern()) { InstanceIdentifier id = buildLearntVpnVipToPortIdentifier(vpnName, prefix); MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.OPERATIONAL, id); @@ -1247,7 +1028,7 @@ public final class VpnUtil { InstanceIdentifier vpnInterfaceOpId = VpnUtil .getVpnInterfaceOpDataEntryIdentifier(vpnInterface, vpnName); InstanceIdentifier path = vpnInterfaceOpId.augmentation(AdjacenciesOp.class); - Optional adjacenciesOp = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, path); + Optional adjacenciesOp = read(LogicalDatastoreType.OPERATIONAL, path); if (adjacenciesOp.isPresent()) { InstanceIdentifier adjacencyIdentifier = InstanceIdentifier.builder(VpnInterfaces.class) .child(VpnInterface.class, new VpnInterfaceKey(vpnInterface)).augmentation(Adjacencies.class) @@ -1259,6 +1040,20 @@ public final class VpnUtil { } } + public void removeMipAdjacency(String vpnInterface, String ipAddress) { + String prefix = VpnUtil.getIpPrefix(ipAddress); + InstanceIdentifier adjacencyIdentifier = getAdjacencyIdentifier(vpnInterface, prefix); + try { + SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, adjacencyIdentifier); + } catch (TransactionCommitFailedException e) { + if (e.getCause() instanceof ModifiedNodeDoesNotExistException) { + LOG.debug("vpnInterface {} is already deleted. prefix={}", vpnInterface, prefix); + } else { + LOG.error("Failed to delete adjacency for vpnInterface {}, prefix {}", vpnInterface, prefix, e); + } + } + } + static InstanceIdentifier buildNetworkMapIdentifier(Uuid networkId) { return InstanceIdentifier.builder(NetworkMaps.class).child(NetworkMap.class, new NetworkMapKey(networkId)).build(); @@ -1274,18 +1069,31 @@ public final class VpnUtil { new VpnPortipToPortKey(fixedIp, vpnName)).build(); } - public static VpnPortipToPort getNeutronPortFromVpnPortFixedIp(DataBroker broker, String vpnName, String fixedIp) { + @Nullable + public VpnPortipToPort getNeutronPortFromVpnPortFixedIp(String vpnName, String fixedIp) { InstanceIdentifier id = buildVpnPortipToPortIdentifier(vpnName, fixedIp); - Optional vpnPortipToPortData = read(broker, LogicalDatastoreType.CONFIGURATION, id); + Optional vpnPortipToPortData = read(LogicalDatastoreType.CONFIGURATION, id); if (vpnPortipToPortData.isPresent()) { return vpnPortipToPortData.get(); } return null; } - static LearntVpnVipToPort getLearntVpnVipToPort(DataBroker broker, String vpnName, String fixedIp) { + @Nullable + public static VpnPortipToPort getNeutronPortFromVpnPortFixedIp(TypedReadTransaction confTx, + String vpnName, String fixedIp) { + InstanceIdentifier id = buildVpnPortipToPortIdentifier(vpnName, fixedIp); + try { + return confTx.read(id).get().orNull(); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } + } + + @Nullable + public LearntVpnVipToPort getLearntVpnVipToPort(String vpnName, String fixedIp) { InstanceIdentifier id = buildLearntVpnVipToPortIdentifier(vpnName, fixedIp); - Optional learntVpnVipToPort = read(broker, LogicalDatastoreType.OPERATIONAL, id); + Optional learntVpnVipToPort = read(LogicalDatastoreType.OPERATIONAL, id); if (learntVpnVipToPort.isPresent()) { return learntVpnVipToPort.get(); } @@ -1293,20 +1101,18 @@ public final class VpnUtil { } @Nonnull - public static List getDpnsOnVpn(DataBroker dataBroker, String vpnInstanceName) { + List getDpnsOnVpn(String vpnInstanceName) { List result = new ArrayList<>(); - String rd = getVpnRd(dataBroker, vpnInstanceName); + String rd = getVpnRd(vpnInstanceName); if (rd == null) { LOG.debug("getDpnsOnVpn: Could not find Route-Distinguisher for VpnName={}", vpnInstanceName); return result; } - - VpnInstanceOpDataEntry vpnInstanceOpData = getVpnInstanceOpData(dataBroker, rd); + VpnInstanceOpDataEntry vpnInstanceOpData = getVpnInstanceOpData(rd); if (vpnInstanceOpData == null) { LOG.debug("getDpnsOnVpn: Could not find OpState for VpnName={}", vpnInstanceName); return result; } - List vpnToDpnList = vpnInstanceOpData.getVpnToDpnList(); if (vpnToDpnList == null) { LOG.debug("getDpnsOnVpn: Could not find DPN footprint for VpnName={}", vpnInstanceName); @@ -1318,112 +1124,139 @@ public final class VpnUtil { return result; } - static String getAssociatedExternalNetwork(DataBroker dataBroker, String routerId) { - InstanceIdentifier id = buildRouterIdentifier(routerId); - Optional routerData = read(dataBroker, LogicalDatastoreType.CONFIGURATION, id); - if (routerData.isPresent()) { - Uuid networkId = routerData.get().getNetworkId(); - if (networkId != null) { - return networkId.getValue(); + @Nullable + String getAssociatedExternalRouter(String extIp) { + InstanceIdentifier extRouterInstanceIndentifier = + InstanceIdentifier.builder(ExtRouters.class).build(); + Optional extRouterData = read(LogicalDatastoreType.CONFIGURATION, extRouterInstanceIndentifier); + if (!extRouterData.isPresent()) { + return null; + } + + // We need to find the router associated with the src ip of this packet. + // This case is either SNAT, in which case the src ip is the same as the + // router's external ip, or FIP in which case the src ip is in the router's + // external leg's subnet. We first check the SNAT case because it is much + // cheaper to do so because it does not require (potentially, there is a + // cache) an datastore read of the neutron subnet for each external IP. + + String routerName = null; + + for (Routers routerData : requireNonNullElse(extRouterData.get().getRouters(), + Collections.emptyList())) { + List externalIps = requireNonNullElse(routerData.getExternalIps(), emptyList()); + for (ExternalIps externalIp : externalIps) { + if (Objects.equals(externalIp.getIpAddress(), extIp)) { + routerName = routerData.getRouterName(); + break; + } } } - return null; - } - public static String getAssociatedExternalRouter(DataBroker dataBroker, String extIp) { - InstanceIdentifier extRouterInstanceIndentifier = - InstanceIdentifier.builder(ExtRouters.class).build(); - Optional extRouterData = read(dataBroker, LogicalDatastoreType.CONFIGURATION, - extRouterInstanceIndentifier); - if (extRouterData.isPresent()) { - for (Routers routerData : extRouterData.get().getRouters()) { - List externalIps = routerData.getExternalIps(); - for (ExternalIps externalIp : externalIps) { - if (externalIp.getIpAddress().equals(extIp)) { - return routerData.getRouterName(); - } + if (routerName != null) { + return routerName; + } + + for (Routers routerData : requireNonNullElse(extRouterData.get().getRouters(), + Collections.emptyList())) { + List externalIps = requireNonNullElse(routerData.getExternalIps(), emptyList()); + for (ExternalIps externalIp : externalIps) { + Subnet neutronSubnet = neutronVpnService.getNeutronSubnet(externalIp.getSubnetId()); + if (neutronSubnet == null) { + LOG.warn("Failed to retrieve subnet {} referenced by router {}", + externalIp.getSubnetId(), routerData); + continue; + } + if (NWUtil.isIpAddressInRange(IpAddressBuilder.getDefaultInstance(extIp), neutronSubnet.getCidr())) { + routerName = routerData.getRouterName(); + break; } } } - return null; + + return routerName; } static InstanceIdentifier buildRouterIdentifier(String routerId) { return InstanceIdentifier.builder(ExtRouters.class).child(Routers.class, new RoutersKey(routerId)).build(); } - static Networks getExternalNetwork(DataBroker dataBroker, Uuid networkId) { + @Nullable + Networks getExternalNetwork(Uuid networkId) { InstanceIdentifier netsIdentifier = InstanceIdentifier.builder(ExternalNetworks.class) .child(Networks.class, new NetworksKey(networkId)).build(); - Optional optionalNets = VpnUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, netsIdentifier); + Optional optionalNets = read(LogicalDatastoreType.CONFIGURATION, netsIdentifier); return optionalNets.isPresent() ? optionalNets.get() : null; } - static Uuid getExternalNetworkVpnId(DataBroker dataBroker, Uuid networkId) { - Networks extNetwork = getExternalNetwork(dataBroker, networkId); + @Nullable + Uuid getExternalNetworkVpnId(Uuid networkId) { + Networks extNetwork = getExternalNetwork(networkId); return extNetwork != null ? extNetwork.getVpnid() : null; } - static List getExternalNetworkRouterIds(DataBroker dataBroker, Uuid networkId) { - Networks extNetwork = getExternalNetwork(dataBroker, networkId); - return extNetwork != null ? extNetwork.getRouterIds() : Collections.emptyList(); + @Nonnull + public List getExternalNetworkRouterIds(Uuid networkId) { + Networks extNetwork = getExternalNetwork(networkId); + return extNetwork != null && extNetwork.getRouterIds() != null ? extNetwork.getRouterIds() : emptyList(); } - static Routers getExternalRouter(DataBroker dataBroker, String routerId) { - InstanceIdentifier id = InstanceIdentifier.builder(ExtRouters.class) - .child(Routers.class, new RoutersKey(routerId)).build(); - Optional routerData = read(dataBroker, LogicalDatastoreType.CONFIGURATION, id); + @Nullable + Routers getExternalRouter(String routerId) { + InstanceIdentifier id = InstanceIdentifier.builder(ExtRouters.class).child(Routers.class, + new RoutersKey(routerId)).build(); + Optional routerData = read(LogicalDatastoreType.CONFIGURATION, id); return routerData.isPresent() ? routerData.get() : null; } - static List getAllSubnetGatewayMacAddressesforVpn(DataBroker broker, String vpnName) { - List macAddresses = new ArrayList<>(); - Optional subnetMapsData = - read(broker, LogicalDatastoreType.CONFIGURATION, buildSubnetMapsWildCardPath()); - if (subnetMapsData.isPresent()) { - List subnetMapList = subnetMapsData.get().getSubnetmap(); - if (subnetMapList != null && !subnetMapList.isEmpty()) { - for (Subnetmap subnet : subnetMapList) { - if (subnet.getVpnId() != null && subnet.getVpnId().equals(Uuid.getDefaultInstance(vpnName))) { - String routerIntfMacAddress = subnet.getRouterIntfMacAddress(); - if (routerIntfMacAddress != null && !routerIntfMacAddress.isEmpty()) { - macAddresses.add(subnet.getRouterIntfMacAddress()); - } - } - } - } - } - return macAddresses; + @Nullable + Routers getExternalRouter(TypedReadTransaction tx, String routerId) + throws ExecutionException, InterruptedException { + InstanceIdentifier id = InstanceIdentifier.builder(ExtRouters.class).child(Routers.class, + new RoutersKey(routerId)).build(); + return tx.read(id).get().orNull(); } static InstanceIdentifier buildSubnetMapsWildCardPath() { return InstanceIdentifier.create(Subnetmaps.class); } - public static FlowEntity buildL3vpnGatewayFlow(BigInteger dpId, String gwMacAddress, long vpnId, - long subnetVpnId) { + FlowEntity buildL3vpnGatewayFlow(BigInteger dpId, String gwMacAddress, long vpnId, + long subnetVpnId) { List mkMatches = new ArrayList<>(); + Subnetmap smap = null; mkMatches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID)); mkMatches.add(new MatchEthernetDestination(new MacAddress(gwMacAddress))); List mkInstructions = new ArrayList<>(); mkInstructions.add(new InstructionGotoTable(NwConstants.L3_FIB_TABLE)); if (subnetVpnId != VpnConstants.INVALID_ID) { + String vpnName = getVpnName(subnetVpnId); + if (vpnName != null) { + smap = getSubnetmapFromItsUuid(Uuid.getDefaultInstance(vpnName)); + if (smap != null && smap.getSubnetIp() != null) { + IpVersionChoice ipVersionChoice = getIpVersionFromString(smap.getSubnetIp()); + if (ipVersionChoice == IpVersionChoice.IPV4) { + mkMatches.add(MatchEthernetType.IPV4); + } else { + mkMatches.add(MatchEthernetType.IPV6); + } + } + } BigInteger subnetIdMetaData = MetaDataUtil.getVpnIdMetadata(subnetVpnId); mkInstructions.add(new InstructionWriteMetadata(subnetIdMetaData, MetaDataUtil.METADATA_MASK_VRFID)); } - - String flowId = getL3VpnGatewayFlowRef(NwConstants.L3_GW_MAC_TABLE, dpId, vpnId, gwMacAddress); - + String flowId = getL3VpnGatewayFlowRef(NwConstants.L3_GW_MAC_TABLE, dpId, vpnId, gwMacAddress, subnetVpnId); return MDSALUtil.buildFlowEntity(dpId, NwConstants.L3_GW_MAC_TABLE, flowId, 20, flowId, 0, 0, NwConstants.COOKIE_L3_GW_MAC_TABLE, mkMatches, mkInstructions); } - private static String getL3VpnGatewayFlowRef(short l3GwMacTable, BigInteger dpId, long vpnId, String gwMacAddress) { + static String getL3VpnGatewayFlowRef(short l3GwMacTable, BigInteger dpId, long vpnId, String gwMacAddress, + long subnetVpnId) { return gwMacAddress + NwConstants.FLOWID_SEPARATOR + vpnId + NwConstants.FLOWID_SEPARATOR + dpId - + NwConstants.FLOWID_SEPARATOR + l3GwMacTable; + + NwConstants.FLOWID_SEPARATOR + l3GwMacTable + NwConstants.FLOWID_SEPARATOR + subnetVpnId; } - public static void lockSubnet(LockManagerService lockManager, String subnetId) { + void lockSubnet(String subnetId) { TryLockInput input = new TryLockInputBuilder().setLockName(subnetId).setTime(3000L).setTimeUnit(TimeUnits.Milliseconds).build(); Future> result = lockManager.tryLock(input); @@ -1442,7 +1275,7 @@ public final class VpnUtil { // We store the cause, which is what we really care about @SuppressWarnings("checkstyle:AvoidHidingCauseException") - public static void unlockSubnet(LockManagerService lockManager, String subnetId) { + public void unlockSubnet(String subnetId) { UnlockInput input = new UnlockInputBuilder().setLockName(subnetId).build(); Future> result = lockManager.unlock(input); try { @@ -1457,20 +1290,20 @@ public final class VpnUtil { } } - static Optional getIpv4GatewayAddressFromInterface(String srcInterface, - INeutronVpnManager neutronVpnService) { + public Optional getGatewayIpAddressFromInterface(MacEntry macEntry) { Optional gatewayIp = Optional.absent(); + String srcInterface = macEntry.getInterfaceName(); + InetAddress hiddenIp = macEntry.getIpAddress(); if (neutronVpnService != null) { //TODO(Gobinath): Need to fix this as assuming port will belong to only one Subnet would be incorrect" Port port = neutronVpnService.getNeutronPort(srcInterface); if (port != null && port.getFixedIps() != null) { - for (FixedIps portIp: port.getFixedIps()) { - if (portIp.getIpAddress().getIpv6Address() != null) { - // Skip IPv6 address - continue; + for (FixedIps portIp : port.getFixedIps()) { + if (doesInterfaceAndHiddenIpAddressTypeMatch(hiddenIp, portIp)) { + gatewayIp = + Optional.of(neutronVpnService.getNeutronSubnet(portIp.getSubnetId()).getGatewayIp()); + break; } - gatewayIp = Optional.of( - neutronVpnService.getNeutronSubnet(portIp.getSubnetId()).getGatewayIp()); } } } else { @@ -1480,27 +1313,30 @@ public final class VpnUtil { return gatewayIp; } - static Optional getGWMacAddressFromInterface(MacEntry macEntry, IpAddress gatewayIp, - DataBroker dataBroker) { + private boolean doesInterfaceAndHiddenIpAddressTypeMatch(InetAddress hiddenIp, FixedIps portIp) { + return hiddenIp instanceof Inet4Address && portIp.getIpAddress().getIpv4Address() != null + || hiddenIp instanceof Inet6Address && portIp.getIpAddress().getIpv6Address() != null; + } + + public Optional getGWMacAddressFromInterface(MacEntry macEntry, IpAddress gatewayIp) { Optional gatewayMac = Optional.absent(); - long vpnId = getVpnId(dataBroker, macEntry.getVpnName()); + long vpnId = getVpnId(macEntry.getVpnName()); InstanceIdentifier vpnIdsInstanceIdentifier = VpnUtil.getVpnIdToVpnInstanceIdentifier(vpnId); Optional - vpnIdsOptional - = VpnUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIdsInstanceIdentifier); + vpnIdsOptional = read(LogicalDatastoreType.CONFIGURATION, vpnIdsInstanceIdentifier); if (!vpnIdsOptional.isPresent()) { LOG.error("getGWMacAddressFromInterface: VPN {} not configured", vpnId); return gatewayMac; } - VpnPortipToPort vpnTargetIpToPort = VpnUtil.getNeutronPortFromVpnPortFixedIp(dataBroker, - macEntry.getVpnName(), gatewayIp.getIpv4Address().getValue()); + VpnPortipToPort vpnTargetIpToPort = + getNeutronPortFromVpnPortFixedIp(macEntry.getVpnName(), gatewayIp.stringValue()); if (vpnTargetIpToPort != null && vpnTargetIpToPort.isSubnetIp()) { gatewayMac = Optional.of(vpnTargetIpToPort.getMacAddress()); } else { - org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds vpnIds = - vpnIdsOptional.get(); + org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911 + .vpn.id.to.vpn.instance.VpnIds vpnIds = vpnIdsOptional.get(); if (vpnIds.isExternalVpn()) { gatewayMac = InterfaceUtils.getMacAddressForInterface(dataBroker, macEntry.getInterfaceName()); } @@ -1508,67 +1344,62 @@ public final class VpnUtil { return gatewayMac; } - public static void setupGwMacIfExternalVpn(DataBroker dataBroker, IMdsalApiManager mdsalManager, BigInteger dpnId, - String interfaceName, long vpnId, WriteTransaction writeInvTxn, int addOrRemove, String gwMac) { + void setupGwMacIfExternalVpn(BigInteger dpnId, String interfaceName, long vpnId, + TypedReadWriteTransaction writeInvTxn, int addOrRemove, String gwMac) + throws ExecutionException, InterruptedException { InstanceIdentifier vpnIdsInstanceIdentifier = getVpnIdToVpnInstanceIdentifier(vpnId); Optional vpnIdsOptional = read( - dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIdsInstanceIdentifier); + .VpnIds> vpnIdsOptional = writeInvTxn.read(vpnIdsInstanceIdentifier).get(); if (vpnIdsOptional.isPresent() && vpnIdsOptional.get().isExternalVpn()) { if (gwMac == null) { LOG.error("setupGwMacIfExternalVpn: Failed to get gwMacAddress for interface {} on dpn {} vpn {}", interfaceName, dpnId.toString(), vpnIdsOptional.get().getVpnInstanceName()); return; } - FlowEntity flowEntity = VpnUtil.buildL3vpnGatewayFlow(dpnId, gwMac, vpnId, VpnConstants.INVALID_ID); + FlowEntity flowEntity = buildL3vpnGatewayFlow(dpnId, gwMac, vpnId, VpnConstants.INVALID_ID); if (addOrRemove == NwConstants.ADD_FLOW) { - mdsalManager.addFlowToTx(flowEntity, writeInvTxn); + mdsalManager.addFlow(writeInvTxn, flowEntity); } else if (addOrRemove == NwConstants.DEL_FLOW) { - mdsalManager.removeFlowToTx(flowEntity, writeInvTxn); + mdsalManager.removeFlow(writeInvTxn, flowEntity); } } } - public static Optional getRouterInterfaceForVpnInterface(DataBroker dataBroker, - String vpnName, - Uuid subnetUuid) { - Optional gwPortOptional = Optional.absent(); - if (subnetUuid != null) { - final Optional gatewayIp = getVpnSubnetGatewayIp(dataBroker, subnetUuid); - if (gatewayIp.isPresent()) { - String gwIp = gatewayIp.get(); - gwPortOptional = Optional.fromNullable(getNeutronPortFromVpnPortFixedIp(dataBroker, vpnName, gwIp)); - } - } - return gwPortOptional; - } - - public static Optional getVpnSubnetGatewayIp(DataBroker dataBroker, final Uuid subnetUuid) { + public Optional getVpnSubnetGatewayIp(final Uuid subnetUuid) { Optional gwIpAddress = Optional.absent(); final SubnetKey subnetkey = new SubnetKey(subnetUuid); final InstanceIdentifier subnetidentifier = InstanceIdentifier.create(Neutron.class) .child(Subnets.class) .child(Subnet.class, subnetkey); - final Optional subnet = read(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetidentifier); + final Optional subnet = read(LogicalDatastoreType.CONFIGURATION, subnetidentifier); if (subnet.isPresent()) { Class ipVersionBase = subnet.get().getIpVersion(); - if (ipVersionBase.equals(IpVersionV4.class)) { - LOG.trace("getVpnSubnetGatewayIp: Obtained subnet {} for vpn interface", - subnet.get().getUuid().getValue()); - IpAddress gwIp = subnet.get().getGatewayIp(); - if (gwIp != null && gwIp.getIpv4Address() != null) { - gwIpAddress = Optional.of(gwIp.getIpv4Address().getValue()); + if (IpVersionV4.class.equals(ipVersionBase)) { + Subnetmap subnetmap = getSubnetmapFromItsUuid(subnetUuid); + if (subnetmap != null && subnetmap.getRouterInterfaceFixedIp() != null) { + LOG.trace("getVpnSubnetGatewayIp: Obtained subnetMap {} for vpn interface", + subnetmap.getId().getValue()); + gwIpAddress = Optional.of(subnetmap.getRouterInterfaceFixedIp()); + } else { + //For direct L3VPN to network association (no router) continue to use subnet-gateway IP + IpAddress gwIp = subnet.get().getGatewayIp(); + if (gwIp != null && gwIp.getIpv4Address() != null) { + gwIpAddress = Optional.of(gwIp.getIpv4Address().getValue()); + } } + LOG.trace("getVpnSubnetGatewayIp: Obtained subnet-gw ip {} for vpn interface", + gwIpAddress.get()); } } return gwIpAddress; } - public static RouterToNaptSwitch getRouterToNaptSwitch(DataBroker dataBroker, String routerName) { + @Nullable + RouterToNaptSwitch getRouterToNaptSwitch(String routerName) { InstanceIdentifier id = InstanceIdentifier.builder(NaptSwitches.class) .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerName)).build(); - Optional routerToNaptSwitchData = read(dataBroker, LogicalDatastoreType.CONFIGURATION, id); + Optional routerToNaptSwitchData = read(LogicalDatastoreType.CONFIGURATION, id); return routerToNaptSwitchData.isPresent() ? routerToNaptSwitchData.get() : null; } @@ -1578,8 +1409,9 @@ public final class VpnUtil { } - public static BigInteger getPrimarySwitchForRouter(DataBroker dataBroker, String routerName) { - RouterToNaptSwitch routerToNaptSwitch = getRouterToNaptSwitch(dataBroker, routerName); + @Nullable + BigInteger getPrimarySwitchForRouter(String routerName) { + RouterToNaptSwitch routerToNaptSwitch = getRouterToNaptSwitch(routerName); return routerToNaptSwitch != null ? routerToNaptSwitch.getPrimarySwitchId() : null; } @@ -1587,28 +1419,23 @@ public final class VpnUtil { return l3Vni != null && l3Vni != 0; } - static boolean isEvpnOverVxLan(Long l2Vni) { //To be used by RT2 - return l2Vni != null && l2Vni != 0; - } - /** * Retrieves the primary rd of a vpn instance * Primary rd will be the first rd in the list of rds configured for a vpn instance * If rd list is empty, primary rd will be vpn instance name * Use this function only during create operation cycles. For other operations, use getVpnRd() method. * - * @param dataBroker dataBroker service reference * @param vpnName Name of the VPN * @return the primary rd of the VPN */ - public static String getPrimaryRd(DataBroker dataBroker, String vpnName) { + public String getPrimaryRd(String vpnName) { // Retrieves the VPN Route Distinguisher by its Vpn instance name - String rd = getVpnRd(dataBroker, vpnName); + String rd = getVpnRd(vpnName); if (rd != null) { return rd; } InstanceIdentifier id = getVpnInstanceIdentifier(vpnName); - Optional vpnInstance = VpnUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id); + Optional vpnInstance = read(LogicalDatastoreType.CONFIGURATION, id); if (vpnInstance.isPresent()) { return getPrimaryRd(vpnInstance.get()); } @@ -1624,7 +1451,7 @@ public final class VpnUtil { * @param vpnInstance Config Vpn Instance Object * @return the primary rd of the VPN */ - public static String getPrimaryRd(VpnInstance vpnInstance) { + static String getPrimaryRd(VpnInstance vpnInstance) { List rds = null; if (vpnInstance != null) { rds = getListOfRdsFromVpnInstance(vpnInstance); @@ -1632,13 +1459,13 @@ public final class VpnUtil { return rds == null || rds.isEmpty() ? vpnInstance.getVpnInstanceName() : rds.get(0); } - public static boolean isBgpVpn(String vpnName, String primaryRd) { + static boolean isBgpVpn(String vpnName, String primaryRd) { return !vpnName.equals(primaryRd); } - static java.util.Optional allocateRdForExtraRouteAndUpdateUsedRdsMap( - DataBroker dataBroker, long vpnId, @Nullable Long parentVpnId, String prefix, String vpnName, - String nextHop, BigInteger dpnId) { + java.util.Optional allocateRdForExtraRouteAndUpdateUsedRdsMap(long vpnId, @Nullable Long parentVpnId, + String prefix, String vpnName, + String nextHop, BigInteger dpnId) { //Check if rd is already allocated for this extraroute behind the same VM. If yes, reuse it. //This is particularly useful during reboot scenarios. java.util.Optional allocatedRd = VpnExtraRouteHelper @@ -1657,16 +1484,16 @@ public final class VpnUtil { // In case of VPN importing the routes, the interface is not present in the VPN // and has to be fetched from the VPN from which it imports Optional prefixToInterface = - getPrefixToInterface(dataBroker, parentVpnId != null ? parentVpnId : vpnId, nextHopIp); + getPrefixToInterface(parentVpnId != null ? parentVpnId : vpnId, nextHopIp); if (prefixToInterface.isPresent() && dpnId.equals(prefixToInterface.get().getDpnId())) { - syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, + syncUpdate(LogicalDatastoreType.CONFIGURATION, VpnExtraRouteHelper.getUsedRdsIdentifier(vpnId, prefix, nextHop), getRdsBuilder(nextHop, usedRd).build()); return java.util.Optional.of(usedRd); } } } - List availableRds = getVpnRdsFromVpnInstanceConfig(dataBroker, vpnName); + List availableRds = getVpnRdsFromVpnInstanceConfig(vpnName); String rd; if (availableRds.isEmpty()) { rd = dpnId.toString(); @@ -1682,9 +1509,8 @@ public final class VpnUtil { // If rd is not allocated for this prefix or if extra route is behind different OVS, select a new rd. rd = availableRds.get(0); } - syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, - VpnExtraRouteHelper.getUsedRdsIdentifier(vpnId, prefix, nextHop), - getRdsBuilder(nextHop, rd).build()); + syncUpdate(LogicalDatastoreType.CONFIGURATION, + VpnExtraRouteHelper.getUsedRdsIdentifier(vpnId, prefix, nextHop), getRdsBuilder(nextHop, rd).build()); return java.util.Optional.ofNullable(rd); } @@ -1698,33 +1524,39 @@ public final class VpnUtil { .augmentation(Adjacencies.class).child(Adjacency.class, new AdjacencyKey(ipAddress)).build(); } + static InstanceIdentifier getVpnInterfaceOpDataEntryAdjacencyIdentifier(String intfName, String vpnName, + String ipAddress) { + return InstanceIdentifier.builder(VpnInterfaceOpData.class) + .child(VpnInterfaceOpDataEntry.class, new VpnInterfaceOpDataEntryKey(intfName, vpnName)) + .augmentation(AdjacenciesOp.class).child(Adjacency.class, new AdjacencyKey(ipAddress)).build(); + } + public static List getIpsListFromExternalIps(List externalIps) { if (externalIps == null) { - return Collections.emptyList(); + return emptyList(); } return externalIps.stream().map(ExternalIps::getIpAddress).collect(Collectors.toList()); } - static void bindService(final String vpnInstanceName, final String interfaceName, DataBroker dataBroker, - boolean isTunnelInterface, JobCoordinator jobCoordinator) { + void bindService(final String vpnInstanceName, final String interfaceName, boolean isTunnelInterface) { jobCoordinator.enqueueJob(interfaceName, - () -> { - WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction(); - BoundServices serviceInfo = isTunnelInterface - ? VpnUtil.getBoundServicesForTunnelInterface(vpnInstanceName, interfaceName) - : getBoundServicesForVpnInterface(dataBroker, vpnInstanceName, interfaceName); - writeTxn.put(LogicalDatastoreType.CONFIGURATION, InterfaceUtils.buildServiceId(interfaceName, - ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME, NwConstants.L3VPN_SERVICE_INDEX)), - serviceInfo, WriteTransaction.CREATE_MISSING_PARENTS); - return Collections.singletonList(writeTxn.submit()); - }, SystemPropertyReader.getDataStoreJobCoordinatorMaxRetries()); - } - - static BoundServices getBoundServicesForVpnInterface(DataBroker broker, String vpnName, String interfaceName) { + () -> Collections.singletonList(txRunner.callWithNewReadWriteTransactionAndSubmit( + Datastore.CONFIGURATION, tx -> { + BoundServices serviceInfo = isTunnelInterface + ? VpnUtil.getBoundServicesForTunnelInterface(vpnInstanceName, interfaceName) + : getBoundServicesForVpnInterface(vpnInstanceName, interfaceName); + tx.put(InterfaceUtils.buildServiceId(interfaceName, + ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME, + NwConstants.L3VPN_SERVICE_INDEX)), + serviceInfo, WriteTransaction.CREATE_MISSING_PARENTS); + })), SystemPropertyReader.getDataStoreJobCoordinatorMaxRetries()); + } + + BoundServices getBoundServicesForVpnInterface(String vpnName, String interfaceName) { List instructions = new ArrayList<>(); int instructionKey = 0; - final long vpnId = VpnUtil.getVpnId(broker, vpnName); + final long vpnId = getVpnId(vpnName); List actions = Collections.singletonList( new ActionRegLoad(0, VpnConstants.VPN_REG_ID, 0, VpnConstants.VPN_ID_LENGTH, vpnId).buildAction()); instructions.add(MDSALUtil.buildApplyActionsInstruction(actions, ++instructionKey)); @@ -1753,52 +1585,44 @@ public final class VpnUtil { return serviceInfo; } - static void unbindService(DataBroker dataBroker, final String vpnInterfaceName, boolean isInterfaceStateDown, - JobCoordinator jobCoordinator) { + void unbindService(final String vpnInterfaceName, boolean isInterfaceStateDown) { if (!isInterfaceStateDown) { jobCoordinator.enqueueJob(vpnInterfaceName, - () -> { - WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction(); - writeTxn.delete(LogicalDatastoreType.CONFIGURATION, - InterfaceUtils.buildServiceId(vpnInterfaceName, - ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME, - NwConstants.L3VPN_SERVICE_INDEX))); - - List> futures = new ArrayList<>(); - futures.add(writeTxn.submit()); - return futures; - }, SystemPropertyReader.getDataStoreJobCoordinatorMaxRetries()); + () -> Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit( + Datastore.CONFIGURATION, tx -> + tx.delete(InterfaceUtils.buildServiceId(vpnInterfaceName, + ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME, + NwConstants.L3VPN_SERVICE_INDEX))))), + SystemPropertyReader.getDataStoreJobCoordinatorMaxRetries()); } } static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId) { - return new FlowEntityBuilder() - .setDpnId(dpnId) - .setTableId(tableId) - .setFlowId(flowId) - .build(); + return new FlowEntityBuilder().setDpnId(dpnId).setTableId(tableId).setFlowId(flowId).build(); } static VrfEntryBase.EncapType getEncapType(boolean isVxLan) { return isVxLan ? VrfEntryBase.EncapType.Vxlan : VrfEntryBase.EncapType.Mplsgre; } - static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets - .Subnets getExternalSubnet(DataBroker dataBroker, Uuid subnetId) { + @Nullable + org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.Subnets + getExternalSubnet(Uuid subnetId) { InstanceIdentifier subnetsIdentifier = InstanceIdentifier.builder(ExternalSubnets.class) .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets .Subnets.class, new SubnetsKey(subnetId)).build(); Optional - optionalSubnets = VpnUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier); + optionalSubnets = read(LogicalDatastoreType.CONFIGURATION, subnetsIdentifier); return optionalSubnets.isPresent() ? optionalSubnets.get() : null; } - static Uuid getSubnetFromExternalRouterByIp(DataBroker dataBroker, Uuid routerId, String ip) { - Routers externalRouter = VpnUtil.getExternalRouter(dataBroker, routerId.getValue()); + @Nullable + public Uuid getSubnetFromExternalRouterByIp(Uuid routerId, String ip) { + Routers externalRouter = getExternalRouter(routerId.getValue()); if (externalRouter != null && externalRouter.getExternalIps() != null) { for (ExternalIps externalIp : externalRouter.getExternalIps()) { - if (externalIp.getIpAddress().equals(ip)) { + if (Objects.equals(externalIp.getIpAddress(), ip)) { return externalIp.getSubnetId(); } } @@ -1811,33 +1635,30 @@ public final class VpnUtil { } static Boolean getIsExternal(Network network) { - return network.getAugmentation(NetworkL3Extension.class) != null - && network.getAugmentation(NetworkL3Extension.class).isExternal(); + return network.augmentation(NetworkL3Extension.class) != null + && network.augmentation(NetworkL3Extension.class).isExternal(); } @SuppressWarnings("checkstyle:linelength") - static Network getNeutronNetwork(DataBroker broker, Uuid networkId) { - Network network = null; + @Nullable + Network getNeutronNetwork(Uuid networkId) { LOG.debug("getNeutronNetwork for {}", networkId.getValue()); InstanceIdentifier inst = InstanceIdentifier.create(Neutron.class).child( org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.Networks.class).child( Network.class, new NetworkKey(networkId)); - Optional net = read(broker, LogicalDatastoreType.CONFIGURATION, inst); - if (net.isPresent()) { - network = net.get(); - } - return network; + return read(LogicalDatastoreType.CONFIGURATION, inst).orNull(); } - public static boolean isEligibleForBgp(String rd, String vpnName, BigInteger dpnId, String networkName) { + public static boolean isEligibleForBgp(@Nullable String rd, @Nullable String vpnName, @Nullable BigInteger dpnId, + @Nullable String networkName) { if (rd != null) { - if (vpnName != null && rd.equals(vpnName)) { + if (rd.equals(vpnName)) { return false; } if (dpnId != null && rd.equals(dpnId.toString())) { return false; } - if (networkName != null && rd.equals(networkName)) { + if (rd.equals(networkName)) { return false; } return true; @@ -1850,9 +1671,9 @@ public final class VpnUtil { + NwConstants.FLOWID_SEPARATOR + vpnName + NwConstants.FLOWID_SEPARATOR + priority; } - static void removeExternalTunnelDemuxFlows(String vpnName, DataBroker broker, IMdsalApiManager mdsalManager) { + void removeExternalTunnelDemuxFlows(String vpnName) { LOG.info("Removing external tunnel flows for vpn {}", vpnName); - for (BigInteger dpnId: NWUtil.getOperativeDPNs(broker)) { + for (BigInteger dpnId: NWUtil.getOperativeDPNs(dataBroker)) { LOG.debug("Removing external tunnel flows for vpn {} from dpn {}", vpnName, dpnId); String flowRef = getFibFlowRef(dpnId, NwConstants.L3VNI_EXTERNAL_TUNNEL_DEMUX_TABLE, vpnName, VpnConstants.DEFAULT_FLOW_PRIORITY); @@ -1862,8 +1683,8 @@ public final class VpnUtil { } } - public static boolean isVpnPendingDelete(DataBroker broker, String rd) { - VpnInstanceOpDataEntry vpnInstanceOpData = getVpnInstanceOpData(broker, rd); + public boolean isVpnPendingDelete(String rd) { + VpnInstanceOpDataEntry vpnInstanceOpData = getVpnInstanceOpData(rd); boolean isVpnPendingDelete = false; if (vpnInstanceOpData == null || vpnInstanceOpData.getVpnState() == VpnInstanceOpDataEntry.VpnState.PendingDelete) { @@ -1872,21 +1693,19 @@ public final class VpnUtil { return isVpnPendingDelete; } - public static List getVpnsImportingMyRoute(final DataBroker broker, final String vpnName) { + public List getVpnsImportingMyRoute(final String vpnName) { List vpnsToImportRoute = new ArrayList<>(); - - final String vpnRd = getVpnRd(broker, vpnName); + final String vpnRd = getVpnRd(vpnName); if (vpnRd == null) { LOG.error("getVpnsImportingMyRoute: vpn {} not present in config DS.", vpnName); return vpnsToImportRoute; } - final VpnInstanceOpDataEntry vpnInstanceOpDataEntry = VpnUtil.getVpnInstanceOpData(broker, vpnRd); + final VpnInstanceOpDataEntry vpnInstanceOpDataEntry = getVpnInstanceOpData(vpnRd); if (vpnInstanceOpDataEntry == null) { LOG.error("getVpnsImportingMyRoute: Could not retrieve vpn instance op data for {}" + " to check for vpns importing the routes", vpnName); return vpnsToImportRoute; } - Predicate excludeVpn = input -> { if (input.getVpnInstanceName() == null) { LOG.error("getVpnsImportingMyRoute.excludeVpn: Received vpn instance with rd {} without a name.", @@ -1895,33 +1714,28 @@ public final class VpnUtil { } return !input.getVpnInstanceName().equals(vpnName); }; - Predicate matchRTs = input -> { Iterable commonRTs = intersection(getRts(vpnInstanceOpDataEntry, VpnTarget.VrfRTType.ExportExtcommunity), getRts(input, VpnTarget.VrfRTType.ImportExtcommunity)); return Iterators.size(commonRTs.iterator()) > 0; }; - - vpnsToImportRoute = getAllVpnInstanceOpData(broker) - .stream() - .filter(excludeVpn) - .filter(matchRTs) + vpnsToImportRoute = getAllVpnInstanceOpData().stream().filter(excludeVpn).filter(matchRTs) .collect(Collectors.toList()); return vpnsToImportRoute; } - public static List getRts(VpnInstanceOpDataEntry vpnInstance, VpnTarget.VrfRTType rtType) { + static List getRts(VpnInstanceOpDataEntry vpnInstance, VpnTarget.VrfRTType rtType) { String name = vpnInstance.getVpnInstanceName(); List rts = new ArrayList<>(); VpnTargets targets = vpnInstance.getVpnTargets(); if (targets == null) { - LOG.info("getRts: vpn targets not available for {}", name); + LOG.debug("getRts: vpn targets not available for {}", name); return rts; } List vpnTargets = targets.getVpnTarget(); if (vpnTargets == null) { - LOG.info("getRts: vpnTarget values not available for {}", name); + LOG.debug("getRts: vpnTarget values not available for {}", name); return rts; } for (VpnTarget target : vpnTargets) { @@ -1934,75 +1748,50 @@ public final class VpnUtil { return rts; } - public static Iterable intersection(final Collection collection1, final Collection collection2) { + static Iterable intersection(final Collection collection1, final Collection collection2) { Set intersection = new HashSet<>(collection1); intersection.retainAll(collection2); return intersection; } /** Get Subnetmap from its Uuid. - * @param broker the data broker for look for data * @param subnetUuid the subnet's Uuid * @return the Subnetmap of Uuid or null if it is not found */ - public static Subnetmap getSubnetmapFromItsUuid(DataBroker broker, Uuid subnetUuid) { - Subnetmap sn = null; + @Nullable + public Subnetmap getSubnetmapFromItsUuid(Uuid subnetUuid) { InstanceIdentifier id = buildSubnetmapIdentifier(subnetUuid); - Optional optionalSn = read(broker, LogicalDatastoreType.CONFIGURATION, id); - if (optionalSn.isPresent()) { - sn = optionalSn.get(); - } - return sn; - } - - public static boolean isSubnetPartOfVpn(Subnetmap sn, String vpnName) { - if (vpnName == null || sn == null || sn.getVpnId() == null) { - return false; - } - if (sn.getVpnId().getValue().equals(vpnName)) { - return true; - } else if (sn.getInternetVpnId() != null - && sn.getInternetVpnId().getValue().equals(vpnName)) { - return true; - } - return false; + return read(LogicalDatastoreType.CONFIGURATION, id).orNull(); } - public static boolean isAdjacencyEligibleToVpnInternet(DataBroker dataBroker, Adjacency adjacency) { + boolean isAdjacencyEligibleToVpnInternet(Adjacency adjacency) { // returns true if BGPVPN Internet and adjacency is IPv6, false otherwise - boolean adjacencyEligible = true; - if (adjacency.getAdjacencyType() == AdjacencyType.ExtraRoute) { - if (FibHelper.isIpv6Prefix(adjacency.getIpAddress())) { - return adjacencyEligible; + boolean adjacencyEligible = false; + IpVersionChoice ipVerChoice = getIpVersionFromString(adjacency.getIpAddress()); + if (ipVerChoice.isIpVersionChosen(IpVersionChoice.IPV6)) { + Subnetmap sn = getSubnetmapFromItsUuid(adjacency.getSubnetId()); + if (sn != null && sn.getInternetVpnId() != null) { + adjacencyEligible = true; } - return false; - } else if (adjacency.getSubnetId() == null) { - return adjacencyEligible; - } - Subnetmap sn = VpnUtil.getSubnetmapFromItsUuid( - dataBroker, adjacency.getSubnetId()); - if (sn != null && sn.getInternetVpnId() != null) { - adjacencyEligible = false; } return adjacencyEligible; } - public static boolean isAdjacencyEligibleToVpn(DataBroker dataBroker, Adjacency adjacency, - String vpnName) { + boolean isAdjacencyEligibleToVpn(Adjacency adjacency, String vpnName) { // returns true if BGPVPN Internet and adjacency is IPv6, false otherwise boolean adjacencyEligible = true; // if BGPVPN internet, return false if subnetmap has not internetVpnId() filled in - if (isBgpVpnInternet(dataBroker, vpnName)) { - return isAdjacencyEligibleToVpnInternet(dataBroker, adjacency); + if (isBgpVpnInternet(vpnName)) { + return isAdjacencyEligibleToVpnInternet(adjacency); } return adjacencyEligible; } - public static String getInternetVpnFromVpnInstanceList(DataBroker dataBroker, - List vpnInstanceList) { + @Nullable + String getInternetVpnFromVpnInstanceList(List vpnInstanceList) { for (VpnInstanceNames vpnInstance : vpnInstanceList) { String vpnName = vpnInstance.getVpnName(); - if (isBgpVpnInternet(dataBroker, vpnName)) { + if (isBgpVpnInternet(vpnName)) { return vpnName; } } @@ -2010,12 +1799,11 @@ public final class VpnUtil { } /** Get boolean true if vpn is bgpvpn internet, false otherwise. - * @param dataBroker databroker for transaction * @param vpnName name of the input VPN * @return true or false */ - public static boolean isBgpVpnInternet(DataBroker dataBroker, String vpnName) { - String primaryRd = getVpnRd(dataBroker, vpnName); + boolean isBgpVpnInternet(String vpnName) { + String primaryRd = getVpnRd(vpnName); if (primaryRd == null) { LOG.error("isBgpVpnInternet VPN {}." + "Primary RD not found", vpnName); @@ -2024,8 +1812,7 @@ public final class VpnUtil { InstanceIdentifier id = InstanceIdentifier.builder(VpnInstanceOpData.class) .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(primaryRd)).build(); - Optional vpnInstanceOpDataEntryOptional = - read(dataBroker, LogicalDatastoreType.OPERATIONAL, id); + Optional vpnInstanceOpDataEntryOptional = read(LogicalDatastoreType.OPERATIONAL, id); if (!vpnInstanceOpDataEntryOptional.isPresent()) { LOG.error("isBgpVpnInternet VPN {}." + "VpnInstanceOpDataEntry not found", vpnName); @@ -2046,7 +1833,6 @@ public final class VpnUtil { * @return the IpVersionChoice of the version or IpVersionChoice.UNDEFINED otherwise */ public static IpVersionChoice getIpVersionFromString(String ipAddress) { - IpVersionChoice ipchoice = IpVersionChoice.UNDEFINED; int indexIpAddress = ipAddress.indexOf('/'); if (indexIpAddress >= 0) { ipAddress = ipAddress.substring(0, indexIpAddress); @@ -2059,16 +1845,14 @@ public final class VpnUtil { return IpVersionChoice.IPV6; } } catch (UnknownHostException | SecurityException e) { - ipchoice = IpVersionChoice.UNDEFINED; + return IpVersionChoice.UNDEFINED; } - return ipchoice; + return IpVersionChoice.UNDEFINED; } - public static ListenableFuture unsetScheduledToRemoveForVpnInterface(ManagedNewTransactionRunner txRunner, - String interfaceName) { - VpnInterfaceBuilder builder = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(interfaceName)) - .setScheduledForRemove(false); - return txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> tx.merge(LogicalDatastoreType.OPERATIONAL, + ListenableFuture unsetScheduledToRemoveForVpnInterface(String interfaceName) { + VpnInterfaceBuilder builder = new VpnInterfaceBuilder().withKey(new VpnInterfaceKey(interfaceName)); + return txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, tx -> tx.merge( VpnUtil.getVpnInterfaceIdentifier(interfaceName), builder.build(), WriteTransaction.CREATE_MISSING_PARENTS)); } @@ -2079,13 +1863,11 @@ public final class VpnUtil { * * @param vpnName the vpnName * @param dpnId the DPN id - * @param dataBroker the data Broker */ - public static void addRouterPortToElanForVlanInDpn(String vpnName, BigInteger dpnId , DataBroker dataBroker) { - Map elanInstanceRouterPortMap = VpnUtil.getElanInstanceRouterPortMap(dataBroker, vpnName); + void addRouterPortToElanForVlanInDpn(String vpnName, BigInteger dpnId) { + Map elanInstanceRouterPortMap = getElanInstanceRouterPortMap(vpnName); for (Entry elanInstanceRouterEntry : elanInstanceRouterPortMap.entrySet()) { - addRouterPortToElanDpn(elanInstanceRouterEntry.getKey(), elanInstanceRouterEntry.getValue(), - vpnName, dpnId, dataBroker); + addRouterPortToElanDpn(elanInstanceRouterEntry.getKey(), elanInstanceRouterEntry.getValue(), dpnId); } } @@ -2095,13 +1877,12 @@ public final class VpnUtil { * * @param vpnName the vpn name * @param dpnId the DPN id - * @param dataBroker the data Broker */ - public static void removeRouterPortFromElanForVlanInDpn(String vpnName, BigInteger dpnId , DataBroker dataBroker) { - Map elanInstanceRouterPortMap = VpnUtil.getElanInstanceRouterPortMap(dataBroker, vpnName); + void removeRouterPortFromElanForVlanInDpn(String vpnName, BigInteger dpnId) { + Map elanInstanceRouterPortMap = getElanInstanceRouterPortMap(vpnName); for (Entry elanInstanceRouterEntry : elanInstanceRouterPortMap.entrySet()) { removeRouterPortFromElanDpn(elanInstanceRouterEntry.getKey(), elanInstanceRouterEntry.getValue(), - vpnName, dpnId, dataBroker); + vpnName, dpnId); } } @@ -2110,15 +1891,13 @@ public final class VpnUtil { * This will create the vlan footprint in all the DPN's which are member of the VPN. * * @param vpnName the vpn name - * @param dataBroker the data broker */ - public static void addRouterPortToElanDpnListForVlaninAllDpn(String vpnName, DataBroker dataBroker) { - Map elanInstanceRouterPortMap = getElanInstanceRouterPortMap(dataBroker, vpnName); - Set dpnList = getDpnInElan(dataBroker, elanInstanceRouterPortMap); + void addRouterPortToElanDpnListForVlaninAllDpn(String vpnName) { + Map elanInstanceRouterPortMap = getElanInstanceRouterPortMap(vpnName); + Set dpnList = getDpnInElan(elanInstanceRouterPortMap); for (BigInteger dpnId : dpnList) { for (Entry elanInstanceRouterEntry : elanInstanceRouterPortMap.entrySet()) { - addRouterPortToElanDpn(elanInstanceRouterEntry.getKey(), elanInstanceRouterEntry.getValue(), - vpnName, dpnId, dataBroker); + addRouterPortToElanDpn(elanInstanceRouterEntry.getKey(), elanInstanceRouterEntry.getValue(), dpnId); } } } @@ -2129,31 +1908,31 @@ public final class VpnUtil { * @param routerInterfacePortId this will add the current subnet router port id to the map for removal * @param elanInstanceName the current elanstance being removed this will be added to map for removal * @param vpnName the vpn name - * @param dataBroker the databroker */ - public static void removeRouterPortFromElanDpnListForVlanInAllDpn(String elanInstanceName, - String routerInterfacePortId, String vpnName, DataBroker dataBroker) { - Map elanInstanceRouterPortMap = getElanInstanceRouterPortMap(dataBroker, vpnName); + void removeRouterPortFromElanDpnListForVlanInAllDpn(String elanInstanceName, + String routerInterfacePortId, String vpnName) { + Map elanInstanceRouterPortMap = getElanInstanceRouterPortMap(vpnName); elanInstanceRouterPortMap.put(elanInstanceName, routerInterfacePortId); - Set dpnList = getDpnInElan(dataBroker, elanInstanceRouterPortMap); + Set dpnList = getDpnInElan(elanInstanceRouterPortMap); for (BigInteger dpnId : dpnList) { for (Entry elanInstanceRouterEntry : elanInstanceRouterPortMap.entrySet()) { removeRouterPortFromElanDpn(elanInstanceRouterEntry.getKey(), elanInstanceRouterEntry.getValue(), - vpnName, dpnId, dataBroker); + vpnName, dpnId); } } } - public static Set getDpnInElan(DataBroker dataBroker, Map elanInstanceRouterPortMap) { + Set getDpnInElan(Map elanInstanceRouterPortMap) { Set dpnIdSet = new HashSet<>(); for (String elanInstanceName : elanInstanceRouterPortMap.keySet()) { InstanceIdentifier elanDpnInterfaceId = getElanDpnOperationalDataPath( elanInstanceName); - Optional dpnInElanInterfaces = VpnUtil.read(dataBroker, - LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId); + Optional dpnInElanInterfaces = read(LogicalDatastoreType.OPERATIONAL, + elanDpnInterfaceId); if (dpnInElanInterfaces.isPresent()) { - List dpnInterfaces = dpnInElanInterfaces.get().getDpnInterfaces(); + List dpnInterfaces = + requireNonNullElse(dpnInElanInterfaces.get().getDpnInterfaces(), emptyList()); for (DpnInterfaces dpnInterface : dpnInterfaces) { dpnIdSet.add(dpnInterface.getDpId()); } @@ -2162,81 +1941,77 @@ public final class VpnUtil { return dpnIdSet; } - public static void addRouterPortToElanDpn(String elanInstanceName, String routerInterfacePortId, String vpnName, - BigInteger dpnId, DataBroker dataBroker) { + void addRouterPortToElanDpn(String elanInstanceName, String routerInterfacePortId, BigInteger dpnId) { InstanceIdentifier elanDpnInterfaceId = getElanDpnInterfaceOperationalDataPath( elanInstanceName,dpnId); - Optional dpnInElanInterfaces = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, - elanDpnInterfaceId); - List elanInterfaceList; - DpnInterfaces dpnInterface; - if (!dpnInElanInterfaces.isPresent()) { - elanInterfaceList = new ArrayList<>(); - } else { - dpnInterface = dpnInElanInterfaces.get(); - elanInterfaceList = dpnInterface.getInterfaces(); - } - if (!elanInterfaceList.contains(routerInterfacePortId)) { - elanInterfaceList.add(routerInterfacePortId); - dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList) - .setKey(new DpnInterfacesKey(dpnId)).build(); - VpnUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, - elanDpnInterfaceId, dpnInterface); + synchronized (elanInstanceName.intern()) { + Optional dpnInElanInterfaces = read(LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId); + List elanInterfaceList; + DpnInterfaces dpnInterface; + if (!dpnInElanInterfaces.isPresent()) { + elanInterfaceList = new ArrayList<>(); + } else { + dpnInterface = dpnInElanInterfaces.get(); + elanInterfaceList = dpnInterface.getInterfaces(); + } + if (!elanInterfaceList.contains(routerInterfacePortId)) { + elanInterfaceList.add(routerInterfacePortId); + dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList) + .withKey(new DpnInterfacesKey(dpnId)).build(); + syncWrite(LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId, dpnInterface); + } } } - public static void removeRouterPortFromElanDpn(String elanInstanceName, String routerInterfacePortId, - String vpnName, BigInteger dpnId, DataBroker dataBroker) { + void removeRouterPortFromElanDpn(String elanInstanceName, String routerInterfacePortId, + String vpnName, BigInteger dpnId) { InstanceIdentifier elanDpnInterfaceId = getElanDpnInterfaceOperationalDataPath( elanInstanceName,dpnId); - Optional dpnInElanInterfaces = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, - elanDpnInterfaceId); - List elanInterfaceList; - DpnInterfaces dpnInterface; - if (!dpnInElanInterfaces.isPresent()) { - LOG.info("No interface in any dpn for {}", vpnName); - return; - } else { - dpnInterface = dpnInElanInterfaces.get(); - elanInterfaceList = dpnInterface.getInterfaces(); - } - if (!elanInterfaceList.contains(routerInterfacePortId)) { - LOG.info("Router port not present in DPN {} for VPN {}", dpnId, vpnName); - return; + synchronized (elanInstanceName.intern()) { + Optional dpnInElanInterfaces = read(LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId); + List elanInterfaceList; + DpnInterfaces dpnInterface; + if (!dpnInElanInterfaces.isPresent()) { + LOG.info("No interface in any dpn for {}", vpnName); + return; + } else { + dpnInterface = dpnInElanInterfaces.get(); + elanInterfaceList = dpnInterface.getInterfaces(); + } + if (!elanInterfaceList.contains(routerInterfacePortId)) { + LOG.info("Router port not present in DPN {} for VPN {}", dpnId, vpnName); + return; + } + elanInterfaceList.remove(routerInterfacePortId); + dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList) + .withKey(new DpnInterfacesKey(dpnId)).build(); + syncWrite(LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId, dpnInterface); } - elanInterfaceList.remove(routerInterfacePortId); - dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList) - .setKey(new DpnInterfacesKey(dpnId)).build(); - VpnUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, - elanDpnInterfaceId, dpnInterface); } - public static ElanInterface getElanInterfaceByElanInterfaceName(DataBroker broker, String elanInterfaceName) { + @Nullable + ElanInterface getElanInterfaceByElanInterfaceName(String elanInterfaceName) { InstanceIdentifier elanInterfaceId = getElanInterfaceConfigurationDataPathId(elanInterfaceName); - return read(broker, LogicalDatastoreType.CONFIGURATION, elanInterfaceId).orNull(); + return read(LogicalDatastoreType.CONFIGURATION, elanInterfaceId).orNull(); } - public static InstanceIdentifier getElanInterfaceConfigurationDataPathId(String interfaceName) { + static InstanceIdentifier getElanInterfaceConfigurationDataPathId(String interfaceName) { return InstanceIdentifier.builder(ElanInterfaces.class) .child(ElanInterface.class, new ElanInterfaceKey(interfaceName)).build(); } - public static Optional getInterface(DataBroker broker, String interfaceName) { - return read(broker, LogicalDatastoreType.CONFIGURATION, getInterfaceIdentifier(interfaceName)); - } - - public static DpnInterfaces getElanInterfaceInfoByElanDpn(DataBroker broker, String elanInstanceName, - BigInteger dpId) { + @Nullable + DpnInterfaces getElanInterfaceInfoByElanDpn(String elanInstanceName, BigInteger dpId) { InstanceIdentifier elanDpnInterfacesId = getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId); - return read(broker, LogicalDatastoreType.OPERATIONAL, elanDpnInterfacesId).orNull(); + return read(LogicalDatastoreType.OPERATIONAL, elanDpnInterfacesId).orNull(); } - public static String getExternalElanInterface(DataBroker broker, String elanInstanceName, BigInteger dpnId, - IInterfaceManager interfaceManager) { - DpnInterfaces dpnInterfaces = getElanInterfaceInfoByElanDpn(broker, elanInstanceName, dpnId); + @Nullable + String getExternalElanInterface(String elanInstanceName, BigInteger dpnId) { + DpnInterfaces dpnInterfaces = getElanInterfaceInfoByElanDpn(elanInstanceName, dpnId); if (dpnInterfaces == null || dpnInterfaces.getInterfaces() == null) { LOG.info("Elan {} does not have interfaces in DPN {}", elanInstanceName, dpnId); return null; @@ -2250,30 +2025,31 @@ public final class VpnUtil { return null; } - public static boolean isVlan(ElanInstance elanInstance) { + static boolean isVlan(ElanInstance elanInstance) { return elanInstance != null && elanInstance.getSegmentType() != null && elanInstance.getSegmentType().isAssignableFrom(SegmentTypeVlan.class) && elanInstance.getSegmentationId() != null && elanInstance.getSegmentationId() != 0; } - public static boolean isVlan(DataBroker databroker , String interfaceName) { - ElanInterface elanInterface = getElanInterfaceByElanInterfaceName(databroker, interfaceName); + boolean isVlan(String interfaceName) { + ElanInterface elanInterface = getElanInterfaceByElanInterfaceName(interfaceName); if (elanInterface == null) { return false; } - ElanInstance elanInstance = getElanInstanceByName(databroker, elanInterface.getElanInstanceName()); + ElanInstance elanInstance = getElanInstanceByName(elanInterface.getElanInstanceName()); return isVlan(elanInstance); } - public static ElanInstance getElanInstanceByName(DataBroker broker, String elanInstanceName) { + @Nullable + ElanInstance getElanInstanceByName(String elanInstanceName) { InstanceIdentifier elanIdentifierId = ElanHelper.getElanInstanceConfigurationDataPath(elanInstanceName); - return read(broker, LogicalDatastoreType.CONFIGURATION, elanIdentifierId).orNull(); + return read(LogicalDatastoreType.CONFIGURATION, elanIdentifierId).orNull(); } - public static String getVpnNameFromElanIntanceName(DataBroker dataBroker, String elanInstanceName) { - Optional subnetMapsData = - read(dataBroker, LogicalDatastoreType.CONFIGURATION, buildSubnetMapsWildCardPath()); + @Nullable + String getVpnNameFromElanIntanceName(String elanInstanceName) { + Optional subnetMapsData = read(LogicalDatastoreType.CONFIGURATION, buildSubnetMapsWildCardPath()); if (subnetMapsData.isPresent()) { List subnetMapList = subnetMapsData.get().getSubnetmap(); if (subnetMapList != null && !subnetMapList.isEmpty()) { @@ -2289,16 +2065,15 @@ public final class VpnUtil { return null; } - public static Map getElanInstanceRouterPortMap(DataBroker dataBroker, String vpnName) { + Map getElanInstanceRouterPortMap(String vpnName) { Map elanInstanceRouterPortMap = new HashMap<>(); - Optional subnetMapsData = - read(dataBroker, LogicalDatastoreType.CONFIGURATION, buildSubnetMapsWildCardPath()); + Optional subnetMapsData = read(LogicalDatastoreType.CONFIGURATION, buildSubnetMapsWildCardPath()); if (subnetMapsData.isPresent()) { List subnetMapList = subnetMapsData.get().getSubnetmap(); if (subnetMapList != null && !subnetMapList.isEmpty()) { for (Subnetmap subnet : subnetMapList) { if (subnet.getVpnId() != null && subnet.getVpnId().getValue().equals(vpnName) - && subnet.getNetworkType().equals(NetworkType.VLAN)) { + && NetworkType.VLAN.equals(subnet.getNetworkType())) { if (subnet.getRouterInterfacePortId() == null || subnet.getNetworkId() == null) { LOG.warn("The RouterInterfacePortId or NetworkId is null"); continue; @@ -2314,9 +2089,9 @@ public final class VpnUtil { return elanInstanceRouterPortMap; } - public static String getRouterPordIdFromElanInstance(DataBroker dataBroker, String elanInstanceName) { - Optional subnetMapsData = - read(dataBroker, LogicalDatastoreType.CONFIGURATION, buildSubnetMapsWildCardPath()); + @Nullable + String getRouterPordIdFromElanInstance(String elanInstanceName) { + Optional subnetMapsData = read(LogicalDatastoreType.CONFIGURATION, buildSubnetMapsWildCardPath()); if (subnetMapsData.isPresent()) { List subnetMapList = subnetMapsData.get().getSubnetmap(); if (subnetMapList != null && !subnetMapList.isEmpty()) { @@ -2332,10 +2107,8 @@ public final class VpnUtil { return null; } - public static boolean shouldPopulateFibForVlan(DataBroker dataBroker, String vpnName, String elanInstanceName, - BigInteger dpnId, IInterfaceManager interfaceManager) { - Map elanInstanceRouterPortMap = VpnUtil - .getElanInstanceRouterPortMap(dataBroker, vpnName); + boolean shouldPopulateFibForVlan(String vpnName, @Nullable String elanInstanceName, BigInteger dpnId) { + Map elanInstanceRouterPortMap = getElanInstanceRouterPortMap(vpnName); boolean shouldPopulateFibForVlan = false; if (!elanInstanceRouterPortMap.isEmpty()) { shouldPopulateFibForVlan = true; @@ -2346,9 +2119,7 @@ public final class VpnUtil { if (elanInstanceName != null && elanInstanceName.equals(currentElanInstance)) { continue; } - String externalinterface = VpnUtil.getExternalElanInterface(dataBroker, - currentElanInstance ,dpnId, - interfaceManager); + String externalinterface = getExternalElanInterface(currentElanInstance ,dpnId); if (externalinterface == null) { shouldPopulateFibForVlan = false; break; @@ -2382,41 +2153,188 @@ public final class VpnUtil { return false; } - public static void removePrefixToInterfaceAdj(DataBroker dataBroker, Adjacency adj, long vpnId, - VpnInterfaceOpDataEntry vpnInterfaceOpDataEntry, - WriteTransaction writeOperTxn) { - Optional prefix = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, - VpnUtil.getPrefixToInterfaceIdentifier(vpnId, - VpnUtil.getIpPrefix(adj.getIpAddress()))); - List prefixToInterface = new ArrayList<>(); - List prefixToInterfaceLocal = new ArrayList<>(); - if (prefix.isPresent()) { - prefixToInterfaceLocal.add(prefix.get()); - } - if (prefixToInterfaceLocal.isEmpty()) { - for (String nh : adj.getNextHopIpList()) { - prefix = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, - VpnUtil.getPrefixToInterfaceIdentifier(vpnId, - VpnUtil.getIpPrefix(nh))); - if (prefix.isPresent()) { - prefixToInterfaceLocal.add(prefix.get()); - } + public static void sendNeighborSolicationToOfGroup(Ipv6NdUtilService ipv6NdUtilService, Ipv6Address srcIpv6Address, + MacAddress srcMac, Ipv6Address dstIpv6Address, Long ofGroupId, BigInteger dpId) { + SendNeighborSolicitationToOfGroupInput input = new SendNeighborSolicitationToOfGroupInputBuilder() + .setSourceIpv6(srcIpv6Address).setSourceLlAddress(srcMac).setTargetIpAddress(dstIpv6Address) + .setOfGroupId(ofGroupId).setDpId(dpId).build(); + try { + Future> result = ipv6NdUtilService + .sendNeighborSolicitationToOfGroup(input); + RpcResult rpcResult = result.get(); + if (!rpcResult.isSuccessful()) { + LOG.error("sendNeighborSolicitationToOfGroup: RPC Call failed for input={} and Errors={}", input, + rpcResult.getErrors()); + } + } catch (InterruptedException | ExecutionException e) { + LOG.error("Failed to send NS packet to ELAN group, input={}", input, e); + } + } + + Set + getRtListForVpn(String vpnName) { + Set rtList = new HashSet<>(); + InstanceIdentifier vpnInstanceId = InstanceIdentifier.builder(VpnInstances.class) + .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build(); + Optional vpnInstanceOptional = read(LogicalDatastoreType.CONFIGURATION, vpnInstanceId); + if (vpnInstanceOptional.isPresent()) { + org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.VpnTargets + vpnTargets = vpnInstanceOptional.get().getIpv4Family().getVpnTargets(); + if (vpnTargets != null && vpnTargets.getVpnTarget() != null) { + rtList.addAll(vpnTargets.getVpnTarget()); } } - if (!prefixToInterfaceLocal.isEmpty()) { - prefixToInterface.addAll(prefixToInterfaceLocal); + else { + LOG.error("getRtListForVpn: Vpn Instance {} not present in config DS", vpnName); } - for (Prefixes pref : prefixToInterface) { - if (VpnUtil.isMatchedPrefixToInterface(pref, vpnInterfaceOpDataEntry)) { - if (writeOperTxn != null) { - writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, - VpnUtil.getPrefixToInterfaceIdentifier(vpnId, pref.getIpAddress())); - } else { - VpnUtil.delete(dataBroker, LogicalDatastoreType.OPERATIONAL, - VpnUtil.getPrefixToInterfaceIdentifier(vpnId, pref.getIpAddress()), - VpnUtil.DEFAULT_CALLBACK); + return rtList; + } + + static InstanceIdentifier getAssociatedSubnetAndVpnIdentifier(String rt, RouteTarget.RtType rtType, + String cidr, String vpnName) { + return InstanceIdentifier.builder(SubnetsAssociatedToRouteTargets.class).child(RouteTarget.class, + new RouteTargetKey(rt, rtType)).child(AssociatedSubnet.class, new AssociatedSubnetKey(cidr)) + .child(AssociatedVpn.class, new AssociatedVpnKey(vpnName)).build(); + } + + static InstanceIdentifier getAssociatedSubnetIdentifier(String rt, RouteTarget.RtType rtType, + String cidr) { + return InstanceIdentifier.builder(SubnetsAssociatedToRouteTargets.class).child(RouteTarget.class, + new RouteTargetKey(rt, rtType)).child(AssociatedSubnet.class, new AssociatedSubnetKey(cidr)).build(); + } + + static AssociatedVpn buildAssociatedSubnetAndVpn(String vpnName) { + return new AssociatedVpnBuilder().setName(vpnName).build(); + } + + static InstanceIdentifier getRouteTargetsIdentifier(String rt, RouteTarget.RtType rtType) { + return InstanceIdentifier.builder(SubnetsAssociatedToRouteTargets.class) + .child(RouteTarget.class, new RouteTargetKey(rt, rtType)).build(); + } + + Set getRouteTargetSet(Set vpnTargets) { + Set routeTargetSet = new HashSet<>(); + for (org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets + .VpnTarget rt : vpnTargets) { + String rtValue = rt.getVrfRTValue(); + switch (rt.getVrfRTType()) { + case ImportExtcommunity: { + Optional exportRouteTargetOptional = read(LogicalDatastoreType.OPERATIONAL, + getRouteTargetsIdentifier(rtValue, RouteTarget.RtType.ERT)); + if (exportRouteTargetOptional.isPresent()) { + routeTargetSet.add(exportRouteTargetOptional.get()); + } + break; + } + case ExportExtcommunity: { + Optional importRouteTargetOptional = read(LogicalDatastoreType.OPERATIONAL, + getRouteTargetsIdentifier(rtValue, RouteTarget.RtType.IRT)); + if (importRouteTargetOptional.isPresent()) { + routeTargetSet.add(importRouteTargetOptional.get()); + } + break; + } + case Both: { + Optional exportRouteTargetOptional = read(LogicalDatastoreType.OPERATIONAL, + getRouteTargetsIdentifier(rtValue, RouteTarget.RtType.ERT)); + if (exportRouteTargetOptional.isPresent()) { + routeTargetSet.add(exportRouteTargetOptional.get()); + } + Optional importRouteTargetOptional = read(LogicalDatastoreType.OPERATIONAL, + getRouteTargetsIdentifier(rtValue, RouteTarget.RtType.IRT)); + if (importRouteTargetOptional.isPresent()) { + routeTargetSet.add(importRouteTargetOptional.get()); + } + break; } + default: + LOG.error("getRouteTargetSet: Invalid rt-type {}", rt.getVrfRTType()); } } + return routeTargetSet; + } + + /* + TODO: (vivek/kiran): Subnet overlap in a VPN detection logic should use subnet allocation pools if available + rather than only CIDR. + Also the Subnet overlap in a VPN detection logic to be addressed for router-based-l3vpns. + */ + static boolean areSubnetsOverlapping(String cidr1, String cidr2) { + final int slash1 = cidr1.indexOf('/'); + final int address1 = addressForCidr(cidr1, slash1); + final int cidrPart1 = maskForCidr(cidr1, slash1); + + final int slash2 = cidr2.indexOf('/'); + final int address2 = addressForCidr(cidr2, slash2); + final int cidrPart2 = maskForCidr(cidr2, slash2); + + final int comparedValue = cidrPart1 <= cidrPart2 ? compare(address1, cidrPart1, address2) + : compare(address2, cidrPart2, address1); + return comparedValue == 0; + } + + private static int addressForCidr(String cidr, int slash) { + return InetAddresses.coerceToInteger(InetAddresses.forString(cidr.substring(0, slash))); + } + + private static int maskForCidr(String cidr, int slash) { + return Integer.parseInt(cidr.substring(slash + 1)); + } + + private static int compare(int address, int cidrPart, int address2) { + int prefix = address2 & computeNetmask(cidrPart); + return address ^ prefix; + } + + private static int computeNetmask(int cidrPart) { + int netmask = 0; + for (int j = 0; j < cidrPart; ++j) { + netmask |= 1 << 31 - j; + } + return netmask; + } + + public static String buildIpMonitorJobKey(String ip, String vpnName) { + return VpnConstants.IP_MONITOR_JOB_PREFIX_KEY + "-" + vpnName + "-" + ip; + } + + public static List getVpnListForVpnInterface(VpnInterface vpnInter) { + return requireNonNullElse(vpnInter.getVpnInstanceNames(), Collections.emptyList()).stream() + .map(VpnInstanceNames::getVpnName).collect(Collectors.toList()); + } + + public void updateVpnInstanceWithRdList(String vpnName, List updatedRdList) { + String primaryRd = getVpnRd(vpnName); + if (primaryRd == null) { + LOG.warn("updateVpnInstanceWithRdList: Unable to retrieve primary RD for the VPN {}. Skip to process " + + "the updated RD list {} ", vpnName, updatedRdList); + return; + } + jobCoordinator.enqueueJob("VPN-" + vpnName, () -> { + VpnInstanceOpDataEntryBuilder builder = new VpnInstanceOpDataEntryBuilder().setVrfId(primaryRd); + builder.setRd(updatedRdList); + return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit( + OPERATIONAL, tx -> { + InstanceIdentifier id = InstanceIdentifier + .builder(VpnInstanceOpData.class).child(VpnInstanceOpDataEntry.class, + new VpnInstanceOpDataEntryKey(primaryRd)).build(); + tx.merge(id, builder.build(), false); + LOG.debug("updateVpnInstanceWithRdList: Successfully updated the VPN {} with list of RDs {}", + vpnName, updatedRdList); + })); + }); + } + + // Use Objects.requireNonNullElse instead with JDK9+ + @Nonnull + public static T requireNonNullElse(@Nullable T obj, @Nonnull T defaultObj) { + return obj != null ? obj : requireNonNull(defaultObj); + } + + public static boolean isDualRouterVpnUpdate(List oldVpnListCopy, List newVpnListCopy) { + return oldVpnListCopy.size() == 2 && newVpnListCopy.size() == 3 + || oldVpnListCopy.size() == 3 && newVpnListCopy.size() == 2; } }