X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=natservice%2Fimpl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fnetvirt%2Fnatservice%2Finternal%2FNatUtil.java;h=76f4315ae875babf0689b46572f7dafbeebcbdd3;hb=97c8a6961453727e929878b58399626485382a1f;hp=8566a9ea0f2b4d2c79edce631f87b998c0d10970;hpb=fd2386273e5dad6c767a00654858c638b0e695ce;p=netvirt.git diff --git a/natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/NatUtil.java b/natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/NatUtil.java index 8566a9ea0f..76f4315ae8 100644 --- a/natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/NatUtil.java +++ b/natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/NatUtil.java @@ -5,14 +5,15 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ - package org.opendaylight.netvirt.natservice.internal; -import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS; +import static java.util.Collections.emptyList; import static org.opendaylight.genius.infra.Datastore.CONFIGURATION; -import com.google.common.base.Optional; import com.google.common.base.Preconditions; +import com.google.common.base.Splitter; +import com.google.common.base.Strings; +import com.google.common.collect.Iterables; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.math.BigInteger; import java.net.InetAddress; @@ -25,17 +26,17 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; +import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Collectors; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.opendaylight.controller.md.sal.binding.api.DataBroker; -import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; -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.apache.commons.net.util.SubnetUtils; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.opendaylight.controller.sal.common.util.Arguments; +import org.opendaylight.genius.datastoreutils.ExpectedDataObjectNotFoundException; import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker; import org.opendaylight.genius.infra.Datastore.Configuration; import org.opendaylight.genius.infra.Datastore.Operational; @@ -45,11 +46,14 @@ import org.opendaylight.genius.infra.TypedReadWriteTransaction; import org.opendaylight.genius.infra.TypedWriteTransaction; import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager; import org.opendaylight.genius.mdsalutil.ActionInfo; +import org.opendaylight.genius.mdsalutil.BucketInfo; import org.opendaylight.genius.mdsalutil.FlowEntity; import org.opendaylight.genius.mdsalutil.FlowEntityBuilder; +import org.opendaylight.genius.mdsalutil.GroupEntity; import org.opendaylight.genius.mdsalutil.InstructionInfo; import org.opendaylight.genius.mdsalutil.MDSALUtil; import org.opendaylight.genius.mdsalutil.MatchInfo; +import org.opendaylight.genius.mdsalutil.MatchInfoBase; import org.opendaylight.genius.mdsalutil.MetaDataUtil; import org.opendaylight.genius.mdsalutil.NwConstants; import org.opendaylight.genius.mdsalutil.actions.ActionGroup; @@ -63,7 +67,11 @@ import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable; import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager; import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType; import org.opendaylight.genius.mdsalutil.matches.MatchMetadata; -import org.opendaylight.infrautils.utils.concurrent.ListenableFutures; +import org.opendaylight.genius.utils.JvmGlobalLocks; +import org.opendaylight.infrautils.utils.concurrent.LoggingFutures; +import org.opendaylight.mdsal.binding.api.DataBroker; +import org.opendaylight.mdsal.common.api.LogicalDatastoreType; +import org.opendaylight.mdsal.common.api.TransactionCommitFailedException; import org.opendaylight.netvirt.bgpmanager.api.IBgpManager; import org.opendaylight.netvirt.elanmanager.api.IElanService; import org.opendaylight.netvirt.fibmanager.api.IFibManager; @@ -72,23 +80,19 @@ import org.opendaylight.netvirt.natservice.ha.NatDataUtil; import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants; import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronUtils; import org.opendaylight.netvirt.vpnmanager.api.IVpnManager; -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; -import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance; -import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey; -import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface; -import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey; +import org.opendaylight.serviceutils.upgrade.UpgradeState; 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.IpPrefix; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefixBuilder; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput; @@ -96,6 +100,15 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406. import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.BridgeRefInfo; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeGre; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput; @@ -108,8 +121,18 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanDpnInterfaces; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesList; @@ -156,6 +179,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn 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.vpn.to.dpn.list.IpAddresses; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.IpAddressesKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExtRouters; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalIpsCounter; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks; @@ -173,6 +197,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev16011 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIpsKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCounters; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCountersKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.external.counters.ExternalIpCounter; @@ -208,23 +233,34 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev16011 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPortKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoType; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoTypeKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnInstances; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnInterfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstance; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstanceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.interfaces.VpnInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.interfaces.VpnInterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortOutput; 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.NeutronvpnService; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps; 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; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.router.interfaces.Interfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.router.interfaces.InterfacesKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.l3.attributes.Routes; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.RouterKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port; +import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.PortKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet; @@ -233,9 +269,16 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev14 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionResubmitRpcAddGroupCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegLoadNodesNodeTableFlowApplyActionsCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad; -import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.Uint16; +import org.opendaylight.yangtools.yang.common.Uint32; +import org.opendaylight.yangtools.yang.common.Uint64; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -243,31 +286,36 @@ public final class NatUtil { private static String OF_URI_SEPARATOR = ":"; private static final Logger LOG = LoggerFactory.getLogger(NatUtil.class); + private static final String OTHER_CONFIG_PARAMETERS_DELIMITER = ","; + private static final String OTHER_CONFIG_KEY_VALUE_DELIMITER = ":"; + private static final String PROVIDER_MAPPINGS = "provider_mappings"; + + private NatUtil() { - private NatUtil() { } + } /* getCookieSnatFlow() computes and returns a unique cookie value for the NAT flows using the router ID as the reference value. */ - public static BigInteger getCookieSnatFlow(long routerId) { - return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0110000", 16)).add( - BigInteger.valueOf(routerId)); + public static Uint64 getCookieSnatFlow(long routerId) { + return Uint64.valueOf(NatConstants.COOKIE_NAPT_BASE.toJava().add(new BigInteger("0110000", 16)).add( + BigInteger.valueOf(routerId))); } /* getCookieNaptFlow() computes and returns a unique cookie value for the NAPT flows using the router ID as the reference value. */ - public static BigInteger getCookieNaptFlow(long routerId) { - return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0111000", 16)).add( - BigInteger.valueOf(routerId)); + public static Uint64 getCookieNaptFlow(Uint32 routerId) { + return Uint64.valueOf(NatConstants.COOKIE_NAPT_BASE.toJava().add(new BigInteger("0111000", 16)).add( + BigInteger.valueOf(routerId.longValue()))); } /* getVpnId() returns the VPN ID from the VPN name */ - public static long getVpnId(DataBroker broker, String vpnName) { + public static Uint32 getVpnId(DataBroker broker, @Nullable String vpnName) { if (vpnName == null) { return NatConstants.INVALID_ID; } @@ -279,9 +327,9 @@ public final class NatUtil { SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, LogicalDatastoreType.CONFIGURATION, id); - long vpnId = NatConstants.INVALID_ID; + Uint32 vpnId = NatConstants.INVALID_ID; if (vpnInstance.isPresent()) { - Long vpnIdAsLong = vpnInstance.get().getVpnId(); + Uint32 vpnIdAsLong = vpnInstance.get().getVpnId(); if (vpnIdAsLong != null) { vpnId = vpnIdAsLong; } @@ -289,13 +337,13 @@ public final class NatUtil { return vpnId; } - public static long getVpnId(TypedReadTransaction confTx, String vpnName) { + public static Uint32 getVpnId(TypedReadTransaction confTx, String vpnName) { if (vpnName == null) { return NatConstants.INVALID_ID; } try { - return confTx.read(getVpnInstanceToVpnIdIdentifier(vpnName)).get().toJavaUtil().map( + return confTx.read(getVpnInstanceToVpnIdIdentifier(vpnName)).get().map( org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id .VpnInstance::getVpnId).orElse(NatConstants.INVALID_ID); } catch (InterruptedException | ExecutionException e) { @@ -305,7 +353,7 @@ public final class NatUtil { return NatConstants.INVALID_ID; } - public static Long getNetworkVpnIdFromRouterId(DataBroker broker, long routerId) { + public static Uint32 getNetworkVpnIdFromRouterId(DataBroker broker, Uint32 routerId) { //Get the external network ID from the ExternalRouter model Uuid networkId = NatUtil.getNetworkIdFromRouterId(broker, routerId); if (networkId == null) { @@ -319,10 +367,56 @@ public final class NatUtil { LOG.error("getNetworkVpnIdFromRouterId : vpnUuid is null"); return NatConstants.INVALID_ID; } - Long vpnId = NatUtil.getVpnId(broker, vpnUuid.getValue()); + Uint32 vpnId = NatUtil.getVpnId(broker, vpnUuid.getValue()); return vpnId; } + public static Boolean validateIsIntefacePartofRouter(DataBroker broker, String routerName, String interfaceName) { + InstanceIdentifier vmInterfaceIdentifier = getRoutersInterfacesIdentifier(routerName, + interfaceName); + + Optional routerInterfacesData; + try { + routerInterfacesData = SingleTransactionDataBroker.syncReadOptional(broker, + LogicalDatastoreType.CONFIGURATION, vmInterfaceIdentifier); + } catch (InterruptedException | ExecutionException e) { + LOG.error("Read Failed Exception While read RouterInterface data for router {}", routerName, e); + routerInterfacesData = Optional.empty(); + } + if (routerInterfacesData.isPresent()) { + return Boolean.TRUE; + } else { + return Boolean.FALSE; + } + } + + private static InstanceIdentifier getRoutersInterfacesIdentifier(String routerName, String interfaceName) { + return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn + .rev150602.RouterInterfacesMap.class) + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router + .interfaces.map.RouterInterfaces.class, + new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router + .interfaces.map.RouterInterfacesKey(new Uuid(routerName))) + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces + .map.router.interfaces.Interfaces.class, + new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces + .map.router.interfaces.InterfacesKey(interfaceName)).build(); + } + + private static InstanceIdentifier getRoutersInterfacesIdentifier(String routerName) { + return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn + .rev150602.RouterInterfacesMap.class) + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router + .interfaces.map.RouterInterfaces.class, + new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router + .interfaces.map.RouterInterfacesKey(new Uuid(routerName))).build(); + } + static InstanceIdentifier getRouterPortsId(String routerId) { return InstanceIdentifier.builder(FloatingIpInfo.class) .child(RouterPorts.class, new RouterPortsKey(routerId)).build(); @@ -354,33 +448,39 @@ public final class NatUtil { .instance.to.vpn.id.VpnInstanceKey(vpnName)).build(); } - static String getVpnInstanceFromVpnIdentifier(DataBroker broker, long vpnId) { + @Nullable + static String getVpnInstanceFromVpnIdentifier(DataBroker broker, Uint32 vpnId) { InstanceIdentifier id = InstanceIdentifier.builder(VpnIdToVpnInstance.class) .child(VpnIds.class, new VpnIdsKey(vpnId)).build(); return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, - LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(VpnIds::getVpnInstanceName).orElse(null); + LogicalDatastoreType.CONFIGURATION, id).map(VpnIds::getVpnInstanceName).orElse(null); } /* getFlowRef() returns a string identfier for the SNAT flows using the router ID as the reference. */ - public static String getFlowRef(BigInteger dpnId, short tableId, long routerID, String ip) { - return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants - .FLOWID_SEPARATOR + routerID + NatConstants.FLOWID_SEPARATOR + ip; + public static String getFlowRef(Uint64 dpnId, short tableId, Uint32 routerID, String ip) { + return new StringBuilder().append(NatConstants.NAPT_FLOWID_PREFIX).append(dpnId) + .append(NatConstants.FLOWID_SEPARATOR).append(tableId).append(NatConstants.FLOWID_SEPARATOR) + .append(routerID).append(NatConstants.FLOWID_SEPARATOR).append(ip).toString(); } - public static String getFlowRef(BigInteger dpnId, short tableId, InetAddress destPrefix, long vpnId) { - return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants - .FLOWID_SEPARATOR + destPrefix.getHostAddress() + NatConstants.FLOWID_SEPARATOR + vpnId; + public static String getFlowRef(Uint64 dpnId, short tableId, InetAddress destPrefix, Uint32 vpnId) { + return new StringBuilder().append(NatConstants.NAPT_FLOWID_PREFIX).append(dpnId) + .append(NatConstants.FLOWID_SEPARATOR).append(tableId).append(NatConstants.FLOWID_SEPARATOR) + .append(destPrefix.getHostAddress()).append(NatConstants.FLOWID_SEPARATOR).append(vpnId).toString(); } - public static String getNaptFlowRef(BigInteger dpnId, short tableId, String routerID, String ip, int port) { - return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants - .FLOWID_SEPARATOR + routerID + NatConstants.FLOWID_SEPARATOR + ip + NatConstants.FLOWID_SEPARATOR - + port; + public static String getNaptFlowRef(Uint64 dpnId, short tableId, String routerID, String ip, + int port, String protocol) { + return new StringBuilder().append(NatConstants.NAPT_FLOWID_PREFIX).append(dpnId) + .append(NatConstants.FLOWID_SEPARATOR).append(tableId).append(NatConstants.FLOWID_SEPARATOR) + .append(routerID).append(NatConstants.FLOWID_SEPARATOR).append(ip).append(NatConstants.FLOWID_SEPARATOR) + .append(port).append(NatConstants.FLOWID_SEPARATOR).append(protocol).toString(); } - static Uuid getNetworkIdFromRouterId(DataBroker broker, long routerId) { + @Nullable + static Uuid getNetworkIdFromRouterId(DataBroker broker, Uint32 routerId) { String routerName = getRouterName(broker, routerId); if (routerName == null) { LOG.error("getNetworkIdFromRouterId - empty routerName received"); @@ -389,6 +489,7 @@ public final class NatUtil { return getNetworkIdFromRouterName(broker, routerName); } + @Nullable static Uuid getNetworkIdFromRouterName(DataBroker broker, String routerName) { if (routerName == null) { LOG.error("getNetworkIdFromRouterName - empty routerName received"); @@ -396,7 +497,7 @@ public final class NatUtil { } InstanceIdentifier id = buildRouterIdentifier(routerName); return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, - LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::getNetworkId).orElse(null); + LogicalDatastoreType.CONFIGURATION, id).map(Routers::getNetworkId).orElse(null); } static InstanceIdentifier buildRouterIdentifier(String routerId) { @@ -405,7 +506,7 @@ public final class NatUtil { return routerInstanceIndentifier; } - private static InstanceIdentifier buildRouterIdentifier(Long routerId) { + private static InstanceIdentifier buildRouterIdentifier(Uint32 routerId) { InstanceIdentifier routerIds = InstanceIdentifier.builder(RouterIdName.class) .child(RouterIds.class, new RouterIdsKey(routerId)).build(); return routerIds; @@ -421,50 +522,45 @@ public final class NatUtil { static boolean isSnatEnabledForRouterId(DataBroker broker, String routerId) { InstanceIdentifier id = buildRouterIdentifier(routerId); return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, - LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::isEnableSnat).orElse(false); + LogicalDatastoreType.CONFIGURATION, id).map(Routers::isEnableSnat).orElse(false); } + @Nullable public static Uuid getVpnIdfromNetworkId(DataBroker broker, Uuid networkId) { InstanceIdentifier id = buildNetworkIdentifier(networkId); return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, - LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Networks::getVpnid).orElse(null); + LogicalDatastoreType.CONFIGURATION, id).map(Networks::getVpnid).orElse(null); } @Nullable public static Uuid getVpnIdfromNetworkId(TypedReadTransaction tx, Uuid networkId) { try { - return tx.read(buildNetworkIdentifier(networkId)).get().toJavaUtil().map(Networks::getVpnid).orElse(null); + return tx.read(buildNetworkIdentifier(networkId)).get().map(Networks::getVpnid).orElse(null); } catch (InterruptedException | ExecutionException e) { LOG.error("Error reading network VPN id for {}", networkId, e); return null; } } + @Nullable public static ProviderTypes getProviderTypefromNetworkId(DataBroker broker, Uuid networkId) { InstanceIdentifier id = buildNetworkIdentifier(networkId); return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, - LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Networks::getProviderNetworkType).orElse(null); + LogicalDatastoreType.CONFIGURATION, id).map(Networks::getProviderNetworkType).orElse(null); } @Nullable public static ProviderTypes getProviderTypefromNetworkId(TypedReadTransaction tx, Uuid networkId) { InstanceIdentifier id = buildNetworkIdentifier(networkId); try { - return tx.read(id).get().toJavaUtil().map(Networks::getProviderNetworkType).orElse(null); + return tx.read(id).get().map(Networks::getProviderNetworkType).orElse(null); } catch (InterruptedException | ExecutionException e) { LOG.error("Error retrieving provider type for {}", networkId, e); return null; } } - @Nonnull - public static List getRouterIdsfromNetworkId(DataBroker broker, Uuid networkId) { - InstanceIdentifier id = buildNetworkIdentifier(networkId); - return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, - LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Networks::getRouterIds).orElse( - Collections.emptyList()); - } - + @Nullable static String getAssociatedExternalNetwork(DataBroker dataBroker, String routerId) { InstanceIdentifier id = NatUtil.buildRouterIdentifier(routerId); Optional routerData = @@ -485,7 +581,8 @@ public final class NatUtil { .child(Networks.class, new NetworksKey(networkId)).build(); } - public static BigInteger getPrimaryNaptfromRouterId(DataBroker broker, Long routerId) { + @Nullable + public static Uint64 getPrimaryNaptfromRouterId(DataBroker broker, Uint32 routerId) { // convert routerId to Name String routerName = getRouterName(broker, routerId); if (routerName == null) { @@ -495,27 +592,31 @@ public final class NatUtil { return getPrimaryNaptfromRouterName(broker, routerName); } - public static BigInteger getPrimaryNaptfromRouterName(DataBroker broker, String routerName) { + @Nullable + public static Uint64 getPrimaryNaptfromRouterName(DataBroker broker, String routerName) { if (routerName == null) { LOG.error("getPrimaryNaptfromRouterName - empty routerName received"); return null; } InstanceIdentifier id = buildNaptSwitchIdentifier(routerName); - return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, - LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(RouterToNaptSwitch::getPrimarySwitchId).orElse( - null); + return (SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, + LogicalDatastoreType.CONFIGURATION, id).map(RouterToNaptSwitch::getPrimarySwitchId).orElse( + Uint64.valueOf(0L))); } public static InstanceIdentifier buildNaptSwitchIdentifier(String routerId) { - InstanceIdentifier rtrNaptSw = InstanceIdentifier.builder(NaptSwitches.class) - .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId)).build(); - return rtrNaptSw; + return InstanceIdentifier.builder(NaptSwitches.class).child(RouterToNaptSwitch.class, + new RouterToNaptSwitchKey(routerId)).build(); } - public static String getRouterName(DataBroker broker, Long routerId) { - InstanceIdentifier id = buildRouterIdentifier(routerId); + public static Optional getAllPrimaryNaptSwitches(DataBroker broker) { return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, - LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(RouterIds::getRouterName).orElse(null); + LogicalDatastoreType.CONFIGURATION, getNaptSwitchesIdentifier()); + } + + @Nullable + public static String getRouterName(DataBroker broker, Uint32 routerId) { + return getVpnInstanceFromVpnIdentifier(broker, routerId); } static InstanceIdentifier getVpnInstanceOpDataIdentifier(String vrfId) { @@ -523,7 +624,7 @@ public final class NatUtil { .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vrfId)).build(); } - public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, BigInteger cookie, String flowId) { + public static FlowEntity buildFlowEntity(Uint64 dpnId, short tableId, Uint64 cookie, String flowId) { return new FlowEntityBuilder() .setDpnId(dpnId) .setTableId(tableId) @@ -532,7 +633,7 @@ public final class NatUtil { .build(); } - public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId) { + public static FlowEntity buildFlowEntity(Uint64 dpnId, short tableId, String flowId) { return new FlowEntityBuilder() .setDpnId(dpnId) .setTableId(tableId) @@ -540,12 +641,8 @@ public final class NatUtil { .build(); } - public static long getIpAddress(byte[] rawIpAddress) { - return ((rawIpAddress[0] & 0xFF) << 3 * 8) + ((rawIpAddress[1] & 0xFF) << 2 * 8) - + ((rawIpAddress[2] & 0xFF) << 1 * 8) + (rawIpAddress[3] & 0xFF) & 0xffffffffL; - } - - public static String getEndpointIpAddressForDPN(DataBroker broker, BigInteger dpnId) { + @Nullable + public static String getEndpointIpAddressForDPN(DataBroker broker, Uint64 dpnId) { String nextHopIp = null; InstanceIdentifier tunnelInfoId = InstanceIdentifier.builder(DpnEndpoints.class) @@ -556,25 +653,26 @@ public final class NatUtil { if (tunnelInfo.isPresent()) { List nexthopIpList = tunnelInfo.get().getTunnelEndPoints(); if (nexthopIpList != null && !nexthopIpList.isEmpty()) { - nextHopIp = nexthopIpList.get(0).getIpAddress().getIpv4Address().getValue(); + nextHopIp = nexthopIpList.get(0).getIpAddress().stringValue(); } } return nextHopIp; } + @Nullable public static String getVpnRd(DataBroker broker, String vpnName) { - InstanceIdentifier id = getVpnInstanceToVpnIdIdentifier(vpnName); return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, - LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map( + LogicalDatastoreType.CONFIGURATION, id).map( org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id .VpnInstance::getVrfId).orElse(null); } + @Nullable public static String getVpnRd(TypedReadTransaction tx, String vpnName) { try { - return tx.read(getVpnInstanceToVpnIdIdentifier(vpnName)).get().toJavaUtil().map( + return tx.read(getVpnInstanceToVpnIdIdentifier(vpnName)).get().map( org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id .VpnInstance::getVrfId).orElse(null); } catch (InterruptedException | ExecutionException e) { @@ -583,17 +681,18 @@ public final class NatUtil { } } - public static IpPortExternal getExternalIpPortMap(DataBroker broker, Long routerId, String internalIpAddress, + @Nullable + public static IpPortExternal getExternalIpPortMap(DataBroker broker, Uint32 routerId, String internalIpAddress, String internalPort, NAPTEntryEvent.Protocol protocol) { ProtocolTypes protocolType = NatUtil.getProtocolType(protocol); InstanceIdentifier ipPortMapId = buildIpToPortMapIdentifier(routerId, internalIpAddress, internalPort, protocolType); return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, - LogicalDatastoreType.CONFIGURATION, ipPortMapId).toJavaUtil().map(IpPortMap::getIpPortExternal).orElse( + LogicalDatastoreType.CONFIGURATION, ipPortMapId).map(IpPortMap::getIpPortExternal).orElse( null); } - private static InstanceIdentifier buildIpToPortMapIdentifier(Long routerId, String internalIpAddress, + private static InstanceIdentifier buildIpToPortMapIdentifier(Uint32 routerId, String internalIpAddress, String internalPort, ProtocolTypes protocolType) { return InstanceIdentifier.builder(IntextIpPortMap.class) @@ -607,12 +706,7 @@ public final class NatUtil { .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).build(); } - static VpnInterface getConfiguredVpnInterface(DataBroker broker, String interfaceName) { - InstanceIdentifier interfaceId = getVpnInterfaceIdentifier(interfaceName); - return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, - LogicalDatastoreType.CONFIGURATION, interfaceId).orNull(); - } - + @Nullable public static String getDpnFromNodeConnectorId(NodeConnectorId portId) { /* * NodeConnectorId is of form 'openflow:dpnid:portnum' @@ -625,15 +719,17 @@ public final class NatUtil { return split[1]; } - public static BigInteger getDpIdFromInterface( + public static Uint64 getDpIdFromInterface( org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces .state.Interface ifState) { String lowerLayerIf = ifState.getLowerLayerIf().get(0); NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf); - return new BigInteger(getDpnFromNodeConnectorId(nodeConnectorId)); + return Uint64.valueOf(getDpnFromNodeConnectorId(nodeConnectorId)); } - public static String getRouterIdfromVpnInstance(DataBroker broker, String vpnName) { + + @Nullable + public static String getRouterIdfromVpnInstance(DataBroker broker, String vpnName, String ipAddress) { // returns only router, attached to IPv4 networks InstanceIdentifier vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class) .child(VpnMap.class, new VpnMapKey(new Uuid(vpnName))).build(); @@ -644,23 +740,23 @@ public final class NatUtil { LOG.error("getRouterIdfromVpnInstance : Router not found for vpn : {}", vpnName); return null; } - List routerIdsList = NeutronUtils.getVpnMapRouterIdsListUuid(optionalVpnMap.get().getRouterIds()); + List routerIdsList = NeutronUtils.getVpnMapRouterIdsListUuid( + new ArrayList(optionalVpnMap.get().nonnullRouterIds().values())); if (routerIdsList != null && !routerIdsList.isEmpty()) { for (Uuid routerUuid : routerIdsList) { - InstanceIdentifier routerIdentifier = buildNeutronRouterIdentifier(routerUuid); - Optional optRouter = SingleTransactionDataBroker - .syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, - LogicalDatastoreType.CONFIGURATION, routerIdentifier); - if (!optRouter.isPresent()) { - continue; - } - List routes = optRouter.get().getRoutes(); - if (routes == null || routes.isEmpty()) { - continue; - } - for (Routes r : routes) { - if (r.getDestination().getIpv4Prefix() != null) { - return routerUuid.getValue(); + InstanceIdentifier id = buildRouterIdentifier(routerUuid.getValue()); + Optional routerData = + SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, + LogicalDatastoreType.CONFIGURATION, id); + if (routerData.isPresent()) { + List subnetIdsList = routerData.get().getSubnetIds(); + for (Uuid subnetUuid : subnetIdsList) { + String subnetIp = getSubnetIp(broker, subnetUuid); + SubnetUtils subnet = new SubnetUtils(subnetIp); + if (subnet.getInfo().isInRange(ipAddress)) { + return routerUuid.getValue(); + } } } } @@ -669,21 +765,31 @@ public final class NatUtil { return null; } + @Nullable static Uuid getVpnForRouter(DataBroker broker, String routerId) { - Preconditions.checkNotNull(routerId, "dissociateRouter: routerId not found!"); + Preconditions.checkNotNull(routerId, "getVpnForRouter: routerId not found!"); InstanceIdentifier vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build(); Optional optionalVpnMaps = SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, LogicalDatastoreType.CONFIGURATION, vpnMapsIdentifier); if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) { - List allMaps = optionalVpnMaps.get().getVpnMap(); - for (VpnMap vpnMap: allMaps) { + for (VpnMap vpnMap : optionalVpnMaps.get().nonnullVpnMap().values()) { if (routerId.equals(vpnMap.getVpnId().getValue())) { continue; } - List routerIdsList = NeutronUtils.getVpnMapRouterIdsListUuid(vpnMap.getRouterIds()); - if (routerIdsList == null || routerIdsList.isEmpty()) { - return null; + List routerIdsList = NeutronUtils.getVpnMapRouterIdsListUuid( + new ArrayList(vpnMap.nonnullRouterIds().values())); + if (routerIdsList.isEmpty()) { + continue; + } + // Skip router vpnId fetching from internet BGP-VPN + if (vpnMap.getNetworkIds() != null && !vpnMap.getNetworkIds().isEmpty()) { + // We only need to check the first network; if it’s not an external network there’s no + // need to check the rest of the VPN’s network list + if (isExternalNetwork(broker, vpnMap.getNetworkIds().iterator().next())) { + continue; + } } if (routerIdsList.contains(new Uuid(routerId))) { return vpnMap.getVpnId(); @@ -694,13 +800,14 @@ public final class NatUtil { return null; } - static long getAssociatedVpn(DataBroker broker, String routerName) { + static Uint32 getAssociatedVpn(DataBroker broker, String routerName) { InstanceIdentifier routerMappingId = NatUtil.getRouterVpnMappingId(routerName); return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, - LogicalDatastoreType.OPERATIONAL, routerMappingId).toJavaUtil().map(Routermapping::getVpnId).orElse( + LogicalDatastoreType.OPERATIONAL, routerMappingId).map(Routermapping::getVpnId).orElse( NatConstants.INVALID_ID); } + @Nullable public static String getAssociatedVPN(DataBroker dataBroker, Uuid networkId) { Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, networkId); if (vpnUuid == null) { @@ -710,6 +817,7 @@ public final class NatUtil { return vpnUuid.getValue(); } + @Nullable public static String getAssociatedVPN(TypedReadTransaction tx, Uuid networkId) { Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(tx, networkId); if (vpnUuid == null) { @@ -726,15 +834,14 @@ public final class NatUtil { IFibManager fibManager, String vpnName, String rd, - Uuid subnetId, String prefix, String nextHopIp, - String parentVpnRd, - String macAddress, - long label, - long l3vni, + @Nullable String parentVpnRd, + @Nullable String macAddress, + Uint32 label, + Uint32 l3vni, RouteOrigin origin, - BigInteger dpId) { + Uint64 dpId) { try { LOG.info("addPrefixToBGP : Adding Fib entry rd {} prefix {} nextHop {} label {}", rd, prefix, nextHopIp, label); @@ -744,15 +851,16 @@ public final class NatUtil { return; } - addPrefixToInterface(broker, getVpnId(broker, vpnName), null /*interfaceName*/,prefix, dpId, - subnetId, Prefixes.PrefixCue.Nat); + addPrefixToInterface(broker, getVpnId(broker, vpnName), null /*interfaceName*/,prefix, parentVpnRd, + dpId, Prefixes.PrefixCue.Nat); + fibManager.addOrUpdateFibEntry(rd, macAddress, prefix, - Collections.singletonList(nextHopIp), VrfEntry.EncapType.Mplsgre, (int)label, l3vni /*l3vni*/, + Collections.singletonList(nextHopIp), VrfEntry.EncapType.Mplsgre, label, l3vni /*l3vni*/, null /*gatewayMacAddress*/, parentVpnRd, origin, null /*writeTxn*/); if (rd != null && !rd.equalsIgnoreCase(vpnName)) { /* Publish to Bgp only if its an INTERNET VPN */ bgpManager.advertisePrefix(rd, null /*macAddress*/, prefix, Collections.singletonList(nextHopIp), - VrfEntry.EncapType.Mplsgre, (int) label, 0 /*l3vni*/, 0 /*l2vni*/, + VrfEntry.EncapType.Mplsgre, label, Uint32.ZERO /*l3vni*/, Uint32.ZERO /*l2vni*/, null /*gatewayMac*/); } LOG.info("addPrefixToBGP : Added Fib entry rd {} prefix {} nextHop {} label {}", rd, @@ -763,15 +871,16 @@ public final class NatUtil { } } - static void addPrefixToInterface(DataBroker broker, long vpnId, String interfaceName, String ipPrefix, - BigInteger dpId, Uuid subnetId, Prefixes.PrefixCue prefixCue) { + static void addPrefixToInterface(DataBroker broker, Uint32 vpnId, @Nullable String interfaceName, String ipPrefix, + String networkId, Uint64 dpId, Prefixes.PrefixCue prefixCue) { InstanceIdentifier prefixId = InstanceIdentifier.builder(PrefixToInterface.class) .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface .VpnIds.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix .to._interface.VpnIdsKey(vpnId)) .child(Prefixes.class, new PrefixesKey(ipPrefix)).build(); PrefixesBuilder prefixBuilder = new PrefixesBuilder().setDpnId(dpId).setIpAddress(ipPrefix); - prefixBuilder.setVpnInterfaceName(interfaceName).setSubnetId(subnetId).setPrefixCue(prefixCue); + prefixBuilder.setVpnInterfaceName(interfaceName).setPrefixCue(prefixCue); + prefixBuilder.setNetworkId(new Uuid(networkId)); try { SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, prefixId, prefixBuilder.build()); @@ -781,7 +890,7 @@ public final class NatUtil { } } - public static void deletePrefixToInterface(DataBroker broker, long vpnId, String ipPrefix) { + public static void deletePrefixToInterface(DataBroker broker, Uint32 vpnId, String ipPrefix) { try { SingleTransactionDataBroker.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.builder(PrefixToInterface.class) @@ -790,7 +899,7 @@ public final class NatUtil { .prefix.to._interface.VpnIdsKey(vpnId)).child(Prefixes.class, new PrefixesKey(ipPrefix)) .build()); } catch (TransactionCommitFailedException e) { - LOG.error("addPrefixToInterface : Failed to write prefxi-to-interface for vpn-id {}", + LOG.error("deletePrefixToInterface : Failed to delete prefxi-to-interface for vpn-id {}", vpnId, e); } } @@ -807,16 +916,22 @@ public final class NatUtil { return routerInstanceIndentifier; } - @Nonnull - public static List getInternalIpPortListInfo(DataBroker dataBroker, Long routerId, + @NonNull + public static List getInternalIpPortListInfo(DataBroker dataBroker, Uint32 routerId, String internalIpAddress, ProtocolTypes protocolType) { - return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker, + List portList = SingleTransactionDataBroker + .syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, - buildSnatIntIpPortIdentifier(routerId, internalIpAddress, protocolType)).toJavaUtil().map( - IntIpProtoType::getPorts).orElse(Collections.emptyList()); + buildSnatIntIpPortIdentifier(routerId, internalIpAddress, protocolType)).map( + IntIpProtoType::getPorts).orElse(emptyList()); + + if (!portList.isEmpty()) { + portList = new ArrayList<>(portList); + } + return portList; } - public static InstanceIdentifier buildSnatIntIpPortIdentifier(Long routerId, + public static InstanceIdentifier buildSnatIntIpPortIdentifier(Uint32 routerId, String internalIpAddress, ProtocolTypes protocolType) { InstanceIdentifier intIpProtocolTypeId = @@ -841,7 +956,7 @@ public final class NatUtil { String internalIpAddress) { return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, - buildSnatIntIpPortIdentifier(routerId, internalIpAddress)).orNull(); + buildSnatIntIpPortIdentifier(routerId, internalIpAddress)).orElse(null); } public static ProtocolTypes getProtocolType(NAPTEntryEvent.Protocol protocol) { @@ -863,59 +978,76 @@ public final class NatUtil { return "snatmiss." + routerName; } - public static long createGroupId(String groupIdKey, IdManagerService idManager) { - AllocateIdInput getIdInput = new AllocateIdInputBuilder() - .setPoolName(NatConstants.SNAT_IDPOOL_NAME).setIdKey(groupIdKey) - .build(); + public static Uint32 getUniqueId(IdManagerService idManager, String poolName, String idKey) { + + AllocateIdInput getIdInput = (new AllocateIdInputBuilder()).setPoolName(poolName).setIdKey(idKey).build(); try { Future> result = idManager.allocateId(getIdInput); - RpcResult rpcResult = result.get(); - return rpcResult.getResult().getIdValue(); - } catch (NullPointerException | InterruptedException | ExecutionException e) { - LOG.error("createGroupId : Creating Group with Key: {} failed", groupIdKey, e); + RpcResult rpcResult = (RpcResult)result.get(); + return rpcResult.isSuccessful() ? rpcResult.getResult().getIdValue() + : NatConstants.INVALID_ID; + } catch (InterruptedException | ExecutionException e) { + LOG.error("releaseId: Exception when releasing Id for key {} from pool {}", idKey, poolName, e); } - return 0; + return NatConstants.INVALID_ID; + } + + public static Uint32 releaseId(IdManagerService idManager, String poolName, String idKey) { + ReleaseIdInput idInput = new ReleaseIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build(); + try { + Future> result = idManager.releaseId(idInput); + if (result == null || result.get() == null || !result.get().isSuccessful()) { + LOG.error("releaseId: RPC Call to release Id from pool {} with key {} returned with Errors {}", + poolName, idKey, + (result != null && result.get() != null) ? result.get().getErrors() : "RpcResult is null"); + } else { + return Uint32.ONE; + } + } catch (InterruptedException | ExecutionException e) { + LOG.error("releaseId: Exception when releasing Id for key {} from pool {}", idKey, poolName, e); + } + return NatConstants.INVALID_ID; } // TODO Clean up the exception handling @SuppressWarnings("checkstyle:IllegalCatch") public static void removePrefixFromBGP(IBgpManager bgpManager, IFibManager fibManager, - String rd, String prefix, String vpnName, Logger log) { + String rd, String prefix, String vpnName) { try { LOG.debug("removePrefixFromBGP: Removing Fib entry rd {} prefix {}", rd, prefix); - fibManager.removeFibEntry(rd, prefix, null); + fibManager.removeFibEntry(rd, prefix, null, null); if (rd != null && !rd.equalsIgnoreCase(vpnName)) { bgpManager.withdrawPrefix(rd, prefix); } LOG.info("removePrefixFromBGP: Removed Fib entry rd {} prefix {}", rd, prefix); } catch (Exception e) { - log.error("removePrefixFromBGP : Delete prefix for rd {} prefix {} vpnName {} failed", + LOG.error("removePrefixFromBGP : Delete prefix for rd {} prefix {} vpnName {} failed", rd, prefix, vpnName, e); } } - public static IpPortMapping getIportMapping(DataBroker broker, long routerId) { + @Nullable + public static IpPortMapping getIportMapping(DataBroker broker, Uint32 routerId) { return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, - LogicalDatastoreType.CONFIGURATION, getIportMappingIdentifier(routerId)).orNull(); + LogicalDatastoreType.CONFIGURATION, getIportMappingIdentifier(routerId)).orElse(null); } - public static InstanceIdentifier getIportMappingIdentifier(long routerId) { + public static InstanceIdentifier getIportMappingIdentifier(Uint32 routerId) { return InstanceIdentifier.builder(IntextIpPortMap.class) .child(IpPortMapping.class, new IpPortMappingKey(routerId)).build(); } public static InstanceIdentifier getIpMappingBuilder(Long routerId) { - InstanceIdentifier idBuilder = InstanceIdentifier.builder(IntextIpMap.class) + .natservice.rev160111.intext.ip.map.IpMapping> getIpMappingBuilder(Uint32 routerId) { + return InstanceIdentifier.builder(IntextIpMap.class) .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map .IpMapping.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111 - .intext.ip.map.IpMappingKey(routerId)).build(); - return idBuilder; + .intext.ip.map.IpMappingKey(routerId)) + .build(); } - @Nonnull - public static Collection getExternalIpsForRouter(DataBroker dataBroker, Long routerId) { + @NonNull + public static Collection getExternalIpsForRouter(DataBroker dataBroker, Uint32 routerId) { Optional ipMappingOptional = SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker, @@ -923,54 +1055,60 @@ public final class NatUtil { // Ensure there are no duplicates Collection externalIps = new HashSet<>(); if (ipMappingOptional.isPresent()) { - List ipMaps = ipMappingOptional.get().getIpMap(); - for (IpMap ipMap : ipMaps) { + for (IpMap ipMap : ipMappingOptional.get().nonnullIpMap().values()) { externalIps.add(ipMap.getExternalIp()); } } return externalIps; } - @Nonnull + @NonNull public static List getExternalIpsForRouter(DataBroker dataBroker, String routerName) { Routers routerData = NatUtil.getRoutersFromConfigDS(dataBroker, routerName); if (routerData != null) { - return NatUtil.getIpsListFromExternalIps(routerData.getExternalIps()); + return NatUtil.getIpsListFromExternalIps( + new ArrayList(routerData.nonnullExternalIps().values())); } - return Collections.emptyList(); + return emptyList(); } - @Nonnull - public static Map getExternalIpsLabelForRouter(DataBroker dataBroker, Long routerId) { + @NonNull + public static Map getExternalIpsLabelForRouter(DataBroker dataBroker, Uint32 routerId) { Optional ipMappingOptional = SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker, LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId)); - Map externalIpsLabel = new HashMap<>(); + Map externalIpsLabel = new HashMap<>(); if (ipMappingOptional.isPresent()) { - List ipMaps = ipMappingOptional.get().getIpMap(); - for (IpMap ipMap : ipMaps) { + for (IpMap ipMap : ipMappingOptional.get().nonnullIpMap().values()) { externalIpsLabel.put(ipMap.getExternalIp(), ipMap.getLabel()); } } return externalIpsLabel; } - public static String getLeastLoadedExternalIp(DataBroker dataBroker, long segmentId) { + @Nullable + public static String getLeastLoadedExternalIp(DataBroker dataBroker, Uint32 segmentId) { String leastLoadedExternalIp = null; InstanceIdentifier id = InstanceIdentifier.builder(ExternalIpsCounter.class) .child(ExternalCounters.class, new ExternalCountersKey(segmentId)).build(); - Optional externalCountersData = - MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id); + Optional externalCountersData; + try { + externalCountersData = SingleTransactionDataBroker.syncReadOptional(dataBroker, + LogicalDatastoreType.OPERATIONAL, id); + } catch (ExecutionException | InterruptedException e) { + LOG.error("getLeastLoadedExternalIp: Exception while reading ExternalCounters DS for the segmentId {}", + segmentId, e); + return leastLoadedExternalIp; + } if (externalCountersData.isPresent()) { ExternalCounters externalCounter = externalCountersData.get(); - List externalIpCounterList = externalCounter.getExternalIpCounter(); short countOfLstLoadExtIp = 32767; - for (ExternalIpCounter externalIpCounter : externalIpCounterList) { + for (ExternalIpCounter externalIpCounter : externalCounter.nonnullExternalIpCounter().values()) { String curExternalIp = externalIpCounter.getExternalIp(); - short countOfCurExtIp = externalIpCounter.getCounter(); + short countOfCurExtIp = externalIpCounter.getCounter().toJava(); if (countOfCurExtIp < countOfLstLoadExtIp) { countOfLstLoadExtIp = countOfCurExtIp; leastLoadedExternalIp = curExternalIp; @@ -981,6 +1119,7 @@ public final class NatUtil { } @SuppressFBWarnings("PZLA_PREFER_ZERO_LENGTH_ARRAYS") + @Nullable public static String[] getSubnetIpAndPrefix(DataBroker dataBroker, Uuid subnetId) { String subnetIP = getSubnetIp(dataBroker, subnetId); if (subnetIP != null) { @@ -990,6 +1129,7 @@ public final class NatUtil { return null; } + @NonNull public static String[] getSubnetIpAndPrefix(String subnetString) { String[] subnetSplit = subnetString.split("/"); String subnetIp = subnetSplit[0]; @@ -1000,14 +1140,14 @@ public final class NatUtil { return new String[] {subnetIp, subnetPrefix}; } + @Nullable public static String getSubnetIp(DataBroker dataBroker, Uuid subnetId) { InstanceIdentifier subnetmapId = InstanceIdentifier .builder(Subnetmaps.class) .child(Subnetmap.class, new SubnetmapKey(subnetId)) .build(); return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker, - LogicalDatastoreType.CONFIGURATION, subnetmapId).toJavaUtil().map(Subnetmap::getSubnetIp).orElse(null); - + LogicalDatastoreType.CONFIGURATION, subnetmapId).map(Subnetmap::getSubnetIp).orElse(null); } public static String[] getExternalIpAndPrefix(String leastLoadedExtIpAddr) { @@ -1020,25 +1160,25 @@ public final class NatUtil { return new String[] {leastLoadedExtIp, leastLoadedExtIpPrefix}; } - @Nonnull - public static List getDpnsForRouter(DataBroker dataBroker, String routerUuid) { + @NonNull + public static List getDpnsForRouter(DataBroker dataBroker, String routerUuid) { InstanceIdentifier id = InstanceIdentifier.builder(NeutronRouterDpns.class) .child(RouterDpnList.class, new RouterDpnListKey(routerUuid)).build(); Optional routerDpnListData = SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker, LogicalDatastoreType.OPERATIONAL, id); - List dpns = new ArrayList<>(); + List dpns = new ArrayList<>(); if (routerDpnListData.isPresent()) { - List dpnVpninterfacesList = routerDpnListData.get().getDpnVpninterfacesList(); - for (DpnVpninterfacesList dpnVpnInterface : dpnVpninterfacesList) { + for (DpnVpninterfacesList dpnVpnInterface + : routerDpnListData.get().nonnullDpnVpninterfacesList().values()) { dpns.add(dpnVpnInterface.getDpnId()); } } return dpns; } - public static long getBgpVpnId(DataBroker dataBroker, String routerName) { - long bgpVpnId = NatConstants.INVALID_ID; + public static Uint32 getBgpVpnId(DataBroker dataBroker, String routerName) { + Uint32 bgpVpnId = NatConstants.INVALID_ID; Uuid bgpVpnUuid = NatUtil.getVpnForRouter(dataBroker, routerName); if (bgpVpnUuid != null) { bgpVpnId = NatUtil.getVpnId(dataBroker, bgpVpnUuid.getValue()); @@ -1047,9 +1187,9 @@ public final class NatUtil { } static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces - .RouterInterface getConfiguredRouterInterface(DataBroker broker, String interfaceName) { + .@Nullable RouterInterface getConfiguredRouterInterface(DataBroker broker, String interfaceName) { return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, - LogicalDatastoreType.CONFIGURATION, NatUtil.getRouterInterfaceId(interfaceName)).orNull(); + LogicalDatastoreType.CONFIGURATION, NatUtil.getRouterInterfaceId(interfaceName)).orElse(null); } static InstanceIdentifier operTx) throws ExecutionException, InterruptedException { - if (dpId.equals(BigInteger.ZERO)) { + if (dpId.equals(Uint64.ZERO)) { LOG.warn("addToNeutronRouterDpnsMap : Could not retrieve dp id for interface {} " + "to handle router {} association model", interfaceName, routerName); return; @@ -1083,10 +1223,10 @@ public final class NatUtil { if (optionalDpnVpninterfacesList.isPresent()) { LOG.debug("addToNeutronRouterDpnsMap : RouterDpnList already present for the Router {} and DPN {} for the " + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName); - operTx.merge(dpnVpnInterfacesListIdentifier + operTx.mergeParentStructureMerge(dpnVpnInterfacesListIdentifier .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class, - new RouterInterfacesKey(interfaceName)), routerInterface, CREATE_MISSING_PARENTS); + new RouterInterfacesKey(interfaceName)), routerInterface); } else { LOG.debug("addToNeutronRouterDpnsMap : Building new RouterDpnList for the Router {} and DPN {} for the " + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName); @@ -1098,13 +1238,13 @@ public final class NatUtil { routerInterfaces.add(routerInterface); dpnVpnList.setRouterInterfaces(routerInterfaces); routerDpnListBuilder.setDpnVpninterfacesList(Collections.singletonList(dpnVpnList.build())); - operTx.merge(getRouterId(routerName), routerDpnListBuilder.build(), CREATE_MISSING_PARENTS); + operTx.mergeParentStructureMerge(getRouterId(routerName), routerDpnListBuilder.build()); } } - public static void addToDpnRoutersMap(String routerName, String interfaceName, BigInteger dpId, + public static void addToDpnRoutersMap(String routerName, String interfaceName, Uint64 dpId, TypedReadWriteTransaction operTx) throws ExecutionException, InterruptedException { - if (dpId.equals(BigInteger.ZERO)) { + if (dpId.equals(Uint64.ZERO)) { LOG.error("addToDpnRoutersMap : Could not retrieve dp id for interface {} to handle router {} " + "association model", interfaceName, routerName); return; @@ -1119,12 +1259,12 @@ public final class NatUtil { if (optionalDpnRoutersList.isPresent()) { RoutersList routersList = new RoutersListBuilder().withKey(new RoutersListKey(routerName)) .setRouter(routerName).build(); - List routersListFromDs = optionalDpnRoutersList.get().getRoutersList(); - if (!routersListFromDs.contains(routersList)) { + Map keyroutersMapFromDs = optionalDpnRoutersList.get().nonnullRoutersList(); + if (!keyroutersMapFromDs.values().contains(routersList)) { LOG.debug("addToDpnRoutersMap : Router {} not present for the DPN {}" + " in the ODL-L3VPN : DPNRouters map", routerName, dpId); - operTx.merge(dpnRoutersListIdentifier - .child(RoutersList.class, new RoutersListKey(routerName)), routersList, CREATE_MISSING_PARENTS); + operTx.mergeParentStructureMerge(dpnRoutersListIdentifier + .child(RoutersList.class, new RoutersListKey(routerName)), routersList); } else { LOG.debug("addToDpnRoutersMap : Router {} already mapped to the DPN {} in the ODL-L3VPN : " + "DPNRouters map", routerName, dpId); @@ -1137,13 +1277,13 @@ public final class NatUtil { RoutersListBuilder routersListBuilder = new RoutersListBuilder(); routersListBuilder.setRouter(routerName); dpnRoutersListBuilder.setRoutersList(Collections.singletonList(routersListBuilder.build())); - operTx.merge(getDpnRoutersId(dpId), dpnRoutersListBuilder.build(), CREATE_MISSING_PARENTS); + operTx.mergeParentStructureMerge(getDpnRoutersId(dpId), dpnRoutersListBuilder.build()); } } - public static void removeFromNeutronRouterDpnsMap(String routerName, BigInteger dpId, + public static void removeFromNeutronRouterDpnsMap(String routerName, Uint64 dpId, TypedReadWriteTransaction operTx) throws ExecutionException, InterruptedException { - if (dpId.equals(BigInteger.ZERO)) { + if (dpId.equals(Uint64.ZERO)) { LOG.warn("removeFromNeutronRouterDpnsMap : DPN ID is invalid for the router {} ", routerName); return; } @@ -1161,58 +1301,39 @@ public final class NatUtil { } public static void removeFromNeutronRouterDpnsMap(String routerName, String vpnInterfaceName, - OdlInterfaceRpcService ifaceMgrRpcService, @Nonnull TypedReadWriteTransaction operTx) { - BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, vpnInterfaceName); - if (dpId.equals(BigInteger.ZERO)) { - LOG.debug("removeFromNeutronRouterDpnsMap : Could not retrieve dp id for interface {} to handle router {}" - + " dissociation model", vpnInterfaceName, routerName); - return; - } + Uint64 dpId, @NonNull TypedReadWriteTransaction operTx) { InstanceIdentifier routerDpnListIdentifier = getRouterDpnId(routerName, dpId); Optional optionalRouterDpnList; try { optionalRouterDpnList = operTx.read(routerDpnListIdentifier).get(); } catch (InterruptedException | ExecutionException e) { LOG.error("Error reading the router DPN list for {}", routerDpnListIdentifier, e); - optionalRouterDpnList = Optional.absent(); + optionalRouterDpnList = Optional.empty(); } if (optionalRouterDpnList.isPresent()) { List routerInterfaces = - optionalRouterDpnList.get().getRouterInterfaces(); + .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces = + new ArrayList<>(optionalRouterDpnList.get().nonnullRouterInterfaces().values()); org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn - .list.dpn.vpninterfaces.list.RouterInterfaces routerInterface = - new RouterInterfacesBuilder().withKey(new RouterInterfacesKey(vpnInterfaceName)) - .setInterface(vpnInterfaceName).build(); + .list.dpn.vpninterfaces.list.RouterInterfaces routerInterface = + new RouterInterfacesBuilder().withKey(new RouterInterfacesKey(vpnInterfaceName)) + .setInterface(vpnInterfaceName).build(); if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) { if (routerInterfaces.isEmpty()) { operTx.delete(routerDpnListIdentifier); } else { operTx.delete(routerDpnListIdentifier.child( - org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router - .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class, - new RouterInterfacesKey(vpnInterfaceName))); + org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router + .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class, + new RouterInterfacesKey(vpnInterfaceName))); } } } } public static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName, - OdlInterfaceRpcService ifaceMgrRpcService, TypedReadWriteTransaction operTx) - throws ExecutionException, InterruptedException { - BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, vpnInterfaceName); - if (dpId.equals(BigInteger.ZERO)) { - LOG.debug("removeFromDpnRoutersMap : removeFromDpnRoutersMap() : " - + "Could not retrieve DPN ID for interface {} to handle router {} dissociation model", - vpnInterfaceName, routerName); - return; - } - removeFromDpnRoutersMap(broker, routerName, vpnInterfaceName, dpId, ifaceMgrRpcService, operTx); - } - - static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName, - BigInteger curDpnId, OdlInterfaceRpcService ifaceMgrRpcService, TypedReadWriteTransaction operTx) + Uint64 curDpnId, OdlInterfaceRpcService ifaceMgrRpcService, TypedReadWriteTransaction operTx) throws ExecutionException, InterruptedException { /* 1) Get the DpnRoutersList for the DPN. @@ -1264,9 +1385,9 @@ public final class NatUtil { } //Get the VM interfaces for the router on the current DPN only. - List vmInterfaces = routerInterfacesData.get().getInterfaces(); - if (vmInterfaces == null) { + Map vmInterfacesMap + = routerInterfacesData.get().nonnullInterfaces(); + if (vmInterfacesMap == null) { LOG.debug("removeFromDpnRoutersMap : VM interfaces are not present for the router {} in the " + "NeutronVPN - router-interfaces-map", routerName); return; @@ -1275,10 +1396,10 @@ public final class NatUtil { // If the removed VPN interface is the only interface through which the router is connected to the DPN, // then remove RouterList. for (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map - .router.interfaces.Interfaces vmInterface : vmInterfaces) { + .router.interfaces.Interfaces vmInterface : vmInterfacesMap.values()) { String vmInterfaceName = vmInterface.getInterfaceId(); - BigInteger vmDpnId = getDpnForInterface(ifaceMgrRpcService, vmInterfaceName); - if (vmDpnId.equals(BigInteger.ZERO) || !vmDpnId.equals(curDpnId)) { + Uint64 vmDpnId = getDpnForInterface(ifaceMgrRpcService, vmInterfaceName); + if (vmDpnId.equals(Uint64.ZERO) || !vmDpnId.equals(curDpnId)) { LOG.debug("removeFromDpnRoutersMap : DPN ID {} for the removed interface {} is not the same as that of " + "the DPN ID {} for the checked interface {}", curDpnId, vpnInterfaceName, vmDpnId, vmInterfaceName); @@ -1296,24 +1417,14 @@ public final class NatUtil { operTx.delete(routersListIdentifier); } - private static InstanceIdentifier getRoutersInterfacesIdentifier(String routerName) { - return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn - .rev150602.RouterInterfacesMap.class) - .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router - .interfaces.map.RouterInterfaces.class, - new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router - .interfaces.map.RouterInterfacesKey(new Uuid(routerName))).build(); - } - - private static InstanceIdentifier getRoutersList(BigInteger dpnId, String routerName) { + private static InstanceIdentifier getRoutersList(Uint64 dpnId, String routerName) { return InstanceIdentifier.builder(DpnRouters.class) .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId)) .child(RoutersList.class, new RoutersListKey(routerName)).build(); } - public static BigInteger getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) { - BigInteger nodeId = BigInteger.ZERO; + public static Uint64 getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) { + Uint64 nodeId = Uint64.ZERO; try { GetDpidFromInterfaceInput dpIdInput = @@ -1325,28 +1436,28 @@ public final class NatUtil { if (dpIdResult.isSuccessful()) { nodeId = dpIdResult.getResult().getDpid(); } else { - LOG.debug("removeFromDpnRoutersMap : Could not retrieve DPN Id for interface {}", ifName); + LOG.debug("getDpnForInterface : Could not retrieve DPN Id for interface {}", ifName); } } catch (NullPointerException | InterruptedException | ExecutionException e) { - LOG.error("removeFromDpnRoutersMap : Exception when getting dpn for interface {}", ifName, e); + LOG.error("getDpnForInterface : Exception when getting dpn for interface {}", ifName, e); } return nodeId; } - @Nonnull + @NonNull public static List getEgressActionsForInterface(OdlInterfaceRpcService odlInterfaceRpcService, ItmRpcService itmRpcService, IInterfaceManager interfaceManager, String ifName, - Long tunnelKey, boolean internalTunnelInterface) { + Uint32 tunnelKey, boolean internalTunnelInterface) { return getEgressActionsForInterface(odlInterfaceRpcService, itmRpcService, interfaceManager, ifName, tunnelKey, 0, internalTunnelInterface); } - @Nonnull + @NonNull public static List getEgressActionsForInterface(OdlInterfaceRpcService odlInterfaceRpcService, ItmRpcService itmRpcService, IInterfaceManager interfaceManager, - String ifName, Long tunnelKey, int pos, + String ifName, @Nullable Uint32 tunnelKey, int pos, boolean internalTunnelInterface) { LOG.debug("getEgressActionsForInterface : called for interface {}", ifName); GetEgressActionsForInterfaceInputBuilder egressActionsIfmBuilder = @@ -1359,7 +1470,7 @@ public final class NatUtil { } //init builders, ITM/IFM rpc can be called based on type of interface try { - List actions = Collections.emptyList(); + List actions = emptyList(); if (interfaceManager.isItmDirectTunnelsEnabled() && internalTunnelInterface) { RpcResult rpcResult = itmRpcService.getEgressActionsForTunnel(egressActionsItmBuilder.build()).get(); @@ -1367,7 +1478,7 @@ public final class NatUtil { LOG.error("getEgressActionsForTunnels : RPC Call to Get egress actions for Tunnels {} " + "returned with Errors {}", ifName, rpcResult.getErrors()); } else { - actions = rpcResult.getResult().getAction(); + actions = new ArrayList(rpcResult.getResult().nonnullAction().values()); } } else { RpcResult rpcResult = @@ -1376,7 +1487,7 @@ public final class NatUtil { LOG.error("getEgressActionsForInterface : RPC Call to Get egress actions for interface {} " + "returned with Errors {}", ifName, rpcResult.getErrors()); } else { - actions = rpcResult.getResult().getAction(); + actions = new ArrayList(rpcResult.getResult().nonnullAction().values()); } } List listActionInfo = new ArrayList<>(); @@ -1391,17 +1502,17 @@ public final class NatUtil { } else if (actionClass instanceof SetFieldCase) { if (((SetFieldCase) actionClass).getSetField().getVlanMatch() != null) { int vlanVid = ((SetFieldCase) actionClass).getSetField().getVlanMatch().getVlanId() - .getVlanId().getValue(); + .getVlanId().getValue().toJava(); listActionInfo.add(new ActionSetFieldVlanVid(pos++, vlanVid)); } } else if (actionClass instanceof NxActionResubmitRpcAddGroupCase) { - Short tableId = ((NxActionResubmitRpcAddGroupCase) actionClass).getNxResubmit().getTable(); + Short tableId = ((NxActionResubmitRpcAddGroupCase) actionClass).getNxResubmit().getTable().toJava(); listActionInfo.add(new ActionNxResubmit(pos++, tableId)); } else if (actionClass instanceof NxActionRegLoadNodesNodeTableFlowApplyActionsCase) { NxRegLoad nxRegLoad = ((NxActionRegLoadNodesNodeTableFlowApplyActionsCase) actionClass).getNxRegLoad(); - listActionInfo.add(new ActionRegLoad(pos++, NxmNxReg6.class, nxRegLoad.getDst().getStart(), - nxRegLoad.getDst().getEnd(), nxRegLoad.getValue().longValue())); + listActionInfo.add(new ActionRegLoad(pos++, NxmNxReg6.class, nxRegLoad.getDst().getStart().toJava(), + nxRegLoad.getDst().getEnd().toJava(), nxRegLoad.getValue().longValue())); } } return listActionInfo; @@ -1409,14 +1520,15 @@ public final class NatUtil { LOG.error("Exception when egress actions for interface {}", ifName, e); } LOG.error("Error when getting egress actions for interface {}", ifName); - return Collections.emptyList(); + return emptyList(); } + @Nullable public static Port getNeutronPortForRouterGetewayIp(DataBroker broker, IpAddress targetIP) { return getNeutronPortForIp(broker, targetIP, NeutronConstants.DEVICE_OWNER_GATEWAY_INF); } - @Nonnull + @NonNull public static List getNeutronPorts(DataBroker broker) { InstanceIdentifier portsIdentifier = InstanceIdentifier.create(Neutron.class) @@ -1428,20 +1540,20 @@ public final class NatUtil { if (!portsOptional.isPresent() || portsOptional.get().getPort() == null) { LOG.error("getNeutronPorts : No neutron ports found"); - return Collections.emptyList(); + return emptyList(); } - return portsOptional.get().getPort(); + return new ArrayList(portsOptional.get().nonnullPort().values()); } - public static Port getNeutronPortForIp(DataBroker broker, - IpAddress targetIP, String deviceType) { + @Nullable + public static Port getNeutronPortForIp(DataBroker broker, IpAddress targetIP, String deviceType) { List ports = getNeutronPorts( broker); for (Port port : ports) { if (deviceType.equals(port.getDeviceOwner()) && port.getFixedIps() != null) { - for (FixedIps ip : port.getFixedIps()) { + for (FixedIps ip : port.nonnullFixedIps().values()) { if (Objects.equals(ip.getIpAddress(), targetIP)) { return port; } @@ -1452,12 +1564,13 @@ public final class NatUtil { return null; } + @Nullable public static Uuid getSubnetIdForFloatingIp(Port port, IpAddress targetIP) { if (port == null) { LOG.error("getSubnetIdForFloatingIp : port is null"); return null; } - for (FixedIps ip : port.getFixedIps()) { + for (FixedIps ip : port.nonnullFixedIps().values()) { if (Objects.equals(ip.getIpAddress(), targetIP)) { return ip.getSubnetId(); } @@ -1466,22 +1579,30 @@ public final class NatUtil { return null; } + @Nullable public static Subnetmap getSubnetMap(DataBroker broker, Uuid subnetId) { InstanceIdentifier subnetmapId = InstanceIdentifier.builder(Subnetmaps.class) .child(Subnetmap.class, new SubnetmapKey(subnetId)).build(); return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, - LogicalDatastoreType.CONFIGURATION, subnetmapId).orNull(); + LogicalDatastoreType.CONFIGURATION, subnetmapId).orElse(null); } - @Nonnull + @NonNull public static List getSubnetIdsFromNetworkId(DataBroker broker, Uuid networkId) { InstanceIdentifier id = InstanceIdentifier.builder(NetworkMaps.class) .child(NetworkMap.class, new NetworkMapKey(networkId)).build(); - return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, - LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(NetworkMap::getSubnetIdList).orElse( - Collections.emptyList()); + List subnetIdList = SingleTransactionDataBroker + .syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, + LogicalDatastoreType.CONFIGURATION, id).map(NetworkMap::getSubnetIdList).orElse( + emptyList()); + if (!subnetIdList.isEmpty()) { + subnetIdList = new ArrayList<>(subnetIdList); + } + + return subnetIdList; } + @Nullable public static String getSubnetGwMac(DataBroker broker, Uuid subnetId, String vpnName) { if (subnetId == null) { LOG.error("getSubnetGwMac : subnetID is null"); @@ -1533,15 +1654,15 @@ public final class NatUtil { } public static boolean isIPv6Subnet(String prefix) { - return new IpPrefix(prefix.toCharArray()).getIpv6Prefix() != null; + return IpPrefixBuilder.getDefaultInstance(prefix).getIpv6Prefix() != null; } - static InstanceIdentifier getDpnRoutersId(BigInteger dpnId) { + static InstanceIdentifier getDpnRoutersId(Uint64 dpnId) { return InstanceIdentifier.builder(DpnRouters.class) .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId)).build(); } - static InstanceIdentifier getRouterDpnId(String routerName, BigInteger dpnId) { + static InstanceIdentifier getRouterDpnId(String routerName, Uint64 dpnId) { return InstanceIdentifier.builder(NeutronRouterDpns.class) .child(RouterDpnList.class, new RouterDpnListKey(routerName)) .child(DpnVpninterfacesList.class, new DpnVpninterfacesListKey(dpnId)).build(); @@ -1552,17 +1673,19 @@ public final class NatUtil { .child(RouterDpnList.class, new RouterDpnListKey(routerName)).build(); } + @Nullable protected static String getFloatingIpPortMacFromFloatingIpId(DataBroker broker, Uuid floatingIpId) { InstanceIdentifier id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId); return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, - LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map( + LogicalDatastoreType.CONFIGURATION, id).map( FloatingIpIdToPortMapping::getFloatingIpPortMacAddress).orElse(null); } + @Nullable protected static String getFloatingIpPortMacFromFloatingIpId(TypedReadTransaction confTx, Uuid floatingIpId) { try { - return confTx.read(buildfloatingIpIdToPortMappingIdentifier(floatingIpId)).get().toJavaUtil().map( + return confTx.read(buildfloatingIpIdToPortMappingIdentifier(floatingIpId)).get().map( FloatingIpIdToPortMapping::getFloatingIpPortMacAddress).orElse(null); } catch (InterruptedException | ExecutionException e) { LOG.error("Error reading the floating IP port MAC for {}", floatingIpId, e); @@ -1570,10 +1693,11 @@ public final class NatUtil { } } + @Nullable protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(DataBroker broker, Uuid floatingIpId) { InstanceIdentifier id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId); return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, - LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map( + LogicalDatastoreType.CONFIGURATION, id).map( FloatingIpIdToPortMapping::getFloatingIpPortSubnetId).orElse(null); } @@ -1581,7 +1705,7 @@ public final class NatUtil { protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(TypedReadTransaction confTx, Uuid floatingIpId) { try { - return confTx.read(buildfloatingIpIdToPortMappingIdentifier(floatingIpId)).get().toJavaUtil().map( + return confTx.read(buildfloatingIpIdToPortMappingIdentifier(floatingIpId)).get().map( FloatingIpIdToPortMapping::getFloatingIpPortSubnetId).orElse(null); } catch (InterruptedException | ExecutionException e) { LOG.error("Error reading the floating IP port subnet for {}", floatingIpId, e); @@ -1594,11 +1718,12 @@ public final class NatUtil { FloatingIpIdToPortMappingKey(floatingIpId)).build(); } + @Nullable static Interface getInterfaceStateFromOperDS(DataBroker dataBroker, String interfaceName) { InstanceIdentifier ifStateId = buildStateInterfaceId(interfaceName); return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker, - LogicalDatastoreType.OPERATIONAL, ifStateId).orNull(); + LogicalDatastoreType.OPERATIONAL, ifStateId).orElse(null); } static InstanceIdentifier buildStateInterfaceId(String interfaceName) { @@ -1608,27 +1733,27 @@ public final class NatUtil { .child(Interface.class, new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508 .interfaces.state.InterfaceKey(interfaceName)); - InstanceIdentifier id = idBuilder.build(); - return id; + return idBuilder.build(); } + @Nullable public static Routers getRoutersFromConfigDS(DataBroker dataBroker, String routerName) { InstanceIdentifier routerIdentifier = NatUtil.buildRouterIdentifier(routerName); return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker, - LogicalDatastoreType.CONFIGURATION, routerIdentifier).orNull(); + LogicalDatastoreType.CONFIGURATION, routerIdentifier).orElse(null); } @Nullable public static Routers getRoutersFromConfigDS(TypedReadTransaction confTx, String routerName) { try { - return confTx.read(NatUtil.buildRouterIdentifier(routerName)).get().orNull(); + return confTx.read(NatUtil.buildRouterIdentifier(routerName)).get().orElse(null); } catch (InterruptedException | ExecutionException e) { LOG.error("Error reading router {}", routerName, e); return null; } } - static void createRouterIdsConfigDS(DataBroker dataBroker, long routerId, String routerName) { + static void createRouterIdsConfigDS(DataBroker dataBroker, Uint32 routerId, String routerName) { if (routerId == NatConstants.INVALID_ID) { LOG.error("createRouterIdsConfigDS : invalid routerId for routerName {}", routerName); return; @@ -1638,7 +1763,8 @@ public final class NatUtil { MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, buildRouterIdentifier(routerId), rtrs); } - static FlowEntity buildDefaultNATFlowEntityForExternalSubnet(BigInteger dpId, long vpnId, String subnetId, + @Nullable + static FlowEntity buildDefaultNATFlowEntityForExternalSubnet(Uint64 dpId, Uint32 vpnId, String subnetId, IdManagerService idManager) { InetAddress defaultIP = null; try { @@ -1652,21 +1778,26 @@ public final class NatUtil { List matches = new ArrayList<>(); matches.add(MatchEthernetType.IPV4); //add match for vrfid - matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID)); + matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId.longValue()), + MetaDataUtil.METADATA_MASK_VRFID)); List instructions = new ArrayList<>(); List actionsInfo = new ArrayList<>(); - long groupId = createGroupId(NatUtil.getGroupIdKey(subnetId), idManager); - actionsInfo.add(new ActionGroup(groupId)); + Uint32 groupId = getUniqueId(idManager, NatConstants.SNAT_IDPOOL_NAME, NatUtil.getGroupIdKey(subnetId)); + if (groupId == NatConstants.INVALID_ID) { + LOG.error("Unable to get groupId for subnet {} while building defauly flow entity", subnetId); + return null; + } + actionsInfo.add(new ActionGroup(groupId.longValue())); String flowRef = getFlowRef(dpId, NwConstants.L3_FIB_TABLE, defaultIP, vpnId); instructions.add(new InstructionApplyActions(actionsInfo)); - FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.L3_FIB_TABLE, flowRef, + return MDSALUtil.buildFlowEntity(dpId, NwConstants.L3_FIB_TABLE, flowRef, NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0, NwConstants.COOKIE_DNAT_TABLE, matches, instructions); - return flowEntity; } - static String getExtGwMacAddFromRouterId(DataBroker broker, long routerId) { + @Nullable + static String getExtGwMacAddFromRouterId(DataBroker broker, Uint32 routerId) { String routerName = getRouterName(broker, routerId); if (routerName == null) { LOG.error("getExtGwMacAddFromRouterId : empty routerName received"); @@ -1675,16 +1806,17 @@ public final class NatUtil { return getExtGwMacAddFromRouterName(broker, routerName); } + @Nullable static String getExtGwMacAddFromRouterName(DataBroker broker, String routerName) { InstanceIdentifier id = buildRouterIdentifier(routerName); return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, - LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::getExtGwMacAddress).orElse(null); + LogicalDatastoreType.CONFIGURATION, id).map(Routers::getExtGwMacAddress).orElse(null); } @Nullable static String getExtGwMacAddFromRouterName(TypedReadTransaction tx, String routerName) { try { - return tx.read(buildRouterIdentifier(routerName)).get().toJavaUtil().map( + return tx.read(buildRouterIdentifier(routerName)).get().map( Routers::getExtGwMacAddress).orElse(null); } catch (InterruptedException | ExecutionException e) { LOG.error("Error retrieving external gateway MAC address for router {}", routerName, e); @@ -1699,35 +1831,42 @@ public final class NatUtil { return routerInstanceIdentifier; } + @Nullable public static String getNeutronRouterNamebyUuid(DataBroker broker, Uuid routerUuid) { InstanceIdentifier neutronRouterIdentifier = NatUtil.buildNeutronRouterIdentifier(routerUuid); return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, - LogicalDatastoreType.CONFIGURATION, neutronRouterIdentifier).toJavaUtil().map(Router::getName).orElse( + LogicalDatastoreType.CONFIGURATION, neutronRouterIdentifier).map(Router::getName).orElse( null); } - @Nonnull + @NonNull public static List getFloatingIpPortsForRouter(DataBroker broker, Uuid routerUuid) { InstanceIdentifier routerPortsIdentifier = getRouterPortsId(routerUuid.getValue()); - return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, - LogicalDatastoreType.CONFIGURATION, - routerPortsIdentifier).toJavaUtil().map(RouterPorts::getPorts).orElse(Collections.emptyList()); + List portsList = new ArrayList(SingleTransactionDataBroker + .syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, LogicalDatastoreType.CONFIGURATION, + routerPortsIdentifier).map(RouterPorts::nonnullPorts).orElse(Collections.emptyMap()).values()); + + if (!portsList.isEmpty()) { + portsList = new ArrayList<>(portsList); + } + return portsList; } - @Nonnull + @NonNull public static List getRouterUuIdsForVpn(DataBroker broker, Uuid vpnUuid) { InstanceIdentifier externalNwIdentifier = InstanceIdentifier.create(ExternalNetworks.class); Optional externalNwData = SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, LogicalDatastoreType.CONFIGURATION, externalNwIdentifier); if (externalNwData.isPresent()) { - for (Networks externalNw : externalNwData.get().getNetworks()) { + for (Networks externalNw : externalNwData.get().nonnullNetworks().values()) { if (externalNw.getVpnid() != null && externalNw.getVpnid().equals(vpnUuid)) { - return externalNw.getRouterIds(); + @Nullable List routerIds = externalNw.getRouterIds(); + return routerIds != null ? new ArrayList<>(routerIds) : emptyList(); } } } - return Collections.emptyList(); + return emptyList(); } public static boolean isIpInSubnet(String ipAddress, String start, String end) { @@ -1743,8 +1882,8 @@ public final class NatUtil { } } - @Nonnull - public static Collection getExternalSubnetIdsFromExternalIps(List externalIps) { + @NonNull + public static Collection getExternalSubnetIdsFromExternalIps(@Nullable List externalIps) { if (externalIps == null) { return Collections.emptySet(); } @@ -1752,8 +1891,8 @@ public final class NatUtil { return externalIps.stream().map(ExternalIps::getSubnetId).collect(Collectors.toSet()); } - @Nonnull - public static Collection getExternalSubnetIdsForRouter(DataBroker dataBroker, String routerName) { + @NonNull + public static Collection getExternalSubnetIdsForRouter(DataBroker dataBroker, @Nullable String routerName) { if (routerName == null) { LOG.error("getExternalSubnetIdsForRouter : empty routerName received"); return Collections.emptySet(); @@ -1764,19 +1903,20 @@ public final class NatUtil { SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, id); if (routerData.isPresent()) { - return NatUtil.getExternalSubnetIdsFromExternalIps(routerData.get().getExternalIps()); + return NatUtil.getExternalSubnetIdsFromExternalIps( + new ArrayList(routerData.get().nonnullExternalIps().values())); } else { LOG.warn("getExternalSubnetIdsForRouter : No external router data for router {}", routerName); return Collections.emptySet(); } } - @Nonnull + @NonNull protected static Optional getOptionalExternalSubnets(DataBroker dataBroker, Uuid subnetId) { if (subnetId == null) { LOG.warn("getOptionalExternalSubnets : subnetId is null"); - return Optional.absent(); + return Optional.empty(); } InstanceIdentifier getOptionalExternalSubnets(TypedReadTransaction tx, Uuid subnetId) { if (subnetId == null) { LOG.warn("getOptionalExternalSubnets : subnetId is null"); - return Optional.absent(); + return Optional.empty(); } InstanceIdentifier optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(dataBroker, subnetId); @@ -1820,7 +1960,7 @@ public final class NatUtil { return NatConstants.INVALID_ID; } - protected static long getExternalSubnetVpnId(TypedReadTransaction tx, Uuid subnetId) { + protected static Uint32 getExternalSubnetVpnId(TypedReadTransaction tx, Uuid subnetId) { Optional optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(tx, subnetId); @@ -1831,7 +1971,7 @@ public final class NatUtil { return NatConstants.INVALID_ID; } - protected static long getExternalSubnetVpnIdForRouterExternalIp(DataBroker dataBroker, String externalIpAddress, + protected static Uint32 getExternalSubnetVpnIdForRouterExternalIp(DataBroker dataBroker, String externalIpAddress, Routers router) { Uuid externalSubnetId = NatUtil.getExternalSubnetForRouterExternalIp(externalIpAddress, router); if (externalSubnetId != null) { @@ -1841,10 +1981,10 @@ public final class NatUtil { return NatConstants.INVALID_ID; } + @Nullable protected static Uuid getExternalSubnetForRouterExternalIp(String externalIpAddress, Routers router) { externalIpAddress = validateAndAddNetworkMask(externalIpAddress); - List externalIps = router.getExternalIps(); - for (ExternalIps extIp : externalIps) { + for (ExternalIps extIp : router.nonnullExternalIps().values()) { String extIpString = validateAndAddNetworkMask(extIp.getIpAddress()); if (extIpString.equals(externalIpAddress)) { return extIp.getSubnetId(); @@ -1864,26 +2004,27 @@ public final class NatUtil { return result; } - @Nonnull + @NonNull static List getIpsListFromExternalIps(@Nullable List externalIps) { if (externalIps == null) { - return Collections.emptyList(); + return emptyList(); } return externalIps.stream().map(ExternalIps::getIpAddress).collect(Collectors.toList()); } // elan-instances config container + @Nullable public static ElanInstance getElanInstanceByName(String elanInstanceName, DataBroker broker) { InstanceIdentifier elanIdentifierId = getElanInstanceConfigurationDataPath(elanInstanceName); return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, - LogicalDatastoreType.CONFIGURATION, elanIdentifierId).orNull(); + LogicalDatastoreType.CONFIGURATION, elanIdentifierId).orElse(null); } @Nullable public static ElanInstance getElanInstanceByName(TypedReadTransaction tx, String elanInstanceName) { try { - return tx.read(getElanInstanceConfigurationDataPath(elanInstanceName)).get().orNull(); + return tx.read(getElanInstanceConfigurationDataPath(elanInstanceName)).get().orElse(null); } catch (InterruptedException | ExecutionException e) { LOG.error("Error retrieving ELAN instance by name {}", elanInstanceName, e); return null; @@ -1895,101 +2036,101 @@ public final class NatUtil { .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build(); } - public static long getTunnelIdForNonNaptToNaptFlow(DataBroker dataBroker, IElanService elanManager, - IdManagerService idManager, long routerId, String routerName) { + public static Uint64 getTunnelIdForNonNaptToNaptFlow(DataBroker dataBroker, NatOverVxlanUtil natOverVxlanUtil, + IElanService elanManager, IdManagerService idManager, + Uint32 routerId, String routerName) { if (elanManager.isOpenStackVniSemanticsEnforced()) { // Router VNI will be set as tun_id if OpenStackSemantics is enabled - return NatOverVxlanUtil.getRouterVni(idManager, routerName, routerId).longValue(); + return natOverVxlanUtil.getRouterVni(routerName, routerId); } else { return NatEvpnUtil.getTunnelIdForRouter(idManager, dataBroker, routerName, routerId); } } - public static void makePreDnatToSnatTableEntry(IMdsalApiManager mdsalManager, BigInteger naptDpnId, + public static void makePreDnatToSnatTableEntry(IMdsalApiManager mdsalManager, Uint64 naptDpnId, short tableId, TypedWriteTransaction confTx) { LOG.debug("makePreDnatToSnatTableEntry : Create Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ", NwConstants.PDNAT_TABLE, tableId, naptDpnId); - List preDnatToSnatInstructions = new ArrayList<>(); - preDnatToSnatInstructions.add(new InstructionGotoTable(tableId).buildInstruction(0)); + Map preDnatToSnatInstructionsMap = new HashMap(); + preDnatToSnatInstructionsMap.put(new InstructionKey(0), + new InstructionGotoTable(tableId).buildInstruction(0)); List matches = new ArrayList<>(); matches.add(MatchEthernetType.IPV4); String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT"); Flow preDnatToSnatTableFlowEntity = MDSALUtil.buildFlowNew(NwConstants.PDNAT_TABLE,flowRef, 5, flowRef, 0, 0, NwConstants.COOKIE_DNAT_TABLE, - matches, preDnatToSnatInstructions); + matches, preDnatToSnatInstructionsMap); mdsalManager.addFlow(confTx, naptDpnId, preDnatToSnatTableFlowEntity); LOG.debug("makePreDnatToSnatTableEntry : Successfully installed Pre-DNAT flow {} on NAPT DpnId {} ", preDnatToSnatTableFlowEntity, naptDpnId); } - // TODO skitt Fix the exception handling here - @SuppressWarnings("checkstyle:IllegalCatch") - @SuppressFBWarnings("REC_CATCH_EXCEPTION") public static void removePreDnatToSnatTableEntry(TypedReadWriteTransaction confTx, - IMdsalApiManager mdsalManager, BigInteger naptDpnId) { + IMdsalApiManager mdsalManager, Uint64 naptDpnId) throws ExecutionException, InterruptedException { LOG.debug("removePreDnatToSnatTableEntry : Remove Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ", NwConstants.PDNAT_TABLE, NwConstants.INBOUND_NAPT_TABLE, naptDpnId); String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT"); - Flow preDnatToSnatTableFlowEntity = MDSALUtil.buildFlowNew(NwConstants.PDNAT_TABLE,flowRef, - 5, flowRef, 0, 0, NwConstants.COOKIE_DNAT_TABLE, null, null); - try { - mdsalManager.removeFlow(confTx, naptDpnId, preDnatToSnatTableFlowEntity); - } catch (Exception e) { - LOG.error("Error removing flow", e); - throw new RuntimeException("Error removing flow", e); - } + mdsalManager.removeFlow(confTx, naptDpnId, flowRef, NwConstants.PDNAT_TABLE); LOG.debug("removePreDnatToSnatTableEntry: Successfully removed Pre-DNAT flow {} on NAPT DpnId = {}", - preDnatToSnatTableFlowEntity, naptDpnId); + flowRef, naptDpnId); } - private static String getFlowRefPreDnatToSnat(BigInteger dpnId, short tableId, String uniqueId) { + private static String getFlowRefPreDnatToSnat(Uint64 dpnId, short tableId, String uniqueId) { return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NwConstants.FLOWID_SEPARATOR + tableId + NwConstants.FLOWID_SEPARATOR + uniqueId; } - public static Boolean isFloatingIpPresentForDpn(DataBroker dataBroker, BigInteger dpnId, String rd, + public static boolean isFloatingIpPresentForDpn(DataBroker dataBroker, Uint64 dpnId, String rd, String vpnName, String externalIp, Boolean isMoreThanOneFipCheckOnDpn) { InstanceIdentifier id = getVpnToDpnListIdentifier(rd, dpnId); - Optional dpnInVpn = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id); + Optional dpnInVpn; + try { + dpnInVpn = SingleTransactionDataBroker.syncReadOptional(dataBroker, + LogicalDatastoreType.OPERATIONAL, id); + } catch (ExecutionException | InterruptedException e) { + LOG.error("isFloatingIpPresentForDpn: Exception while reading VpnToDpnList DS for the rd {} dpnId {}", + rd, dpnId, e); + return false; + } if (dpnInVpn.isPresent()) { LOG.debug("isFloatingIpPresentForDpn : vpn-to-dpn-list is not empty for vpnName {}, dpn id {}, " + "rd {} and floatingIp {}", vpnName, dpnId, rd, externalIp); try { - List ipAddressList = dpnInVpn.get().getIpAddresses(); - if (ipAddressList != null && !ipAddressList.isEmpty()) { + Map keyIpAddressesMap = dpnInVpn.get().getIpAddresses(); + if (keyIpAddressesMap != null && !keyIpAddressesMap.isEmpty()) { int floatingIpPresentCount = 0; - for (IpAddresses ipAddress: ipAddressList) { - if (!ipAddress.getIpAddress().equals(externalIp) + for (IpAddresses ipAddress: keyIpAddressesMap.values()) { + if (!Objects.equals(ipAddress.getIpAddress(), externalIp) && IpAddresses.IpAddressSource.FloatingIP.equals(ipAddress.getIpAddressSource())) { floatingIpPresentCount++; //Add tunnel table check if (isMoreThanOneFipCheckOnDpn && floatingIpPresentCount > 1) { - return Boolean.TRUE; + return true; } //Remove tunnel table check if (!isMoreThanOneFipCheckOnDpn) { - return Boolean.TRUE; + return true; } } } } else { LOG.debug("isFloatingIpPresentForDpn : vpn-to-dpn-list does not contain any floating IP for DPN {}", dpnId); - return Boolean.FALSE; + return false; } } catch (NullPointerException e) { LOG.error("isFloatingIpPresentForDpn: Exception occurred on getting external IP address from " + "vpn-to-dpn-list on Dpn {}", dpnId, e); - return Boolean.FALSE; + return false; } } - return Boolean.FALSE; + return false; } - private static InstanceIdentifier getVpnToDpnListIdentifier(String rd, BigInteger dpnId) { + private static InstanceIdentifier getVpnToDpnListIdentifier(String rd, Uint64 dpnId) { return InstanceIdentifier.builder(VpnInstanceOpData.class) .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(rd)) .child(VpnToDpnList.class, new VpnToDpnListKey(dpnId)).build(); @@ -1998,26 +2139,16 @@ public final class NatUtil { @Nullable public static String getPrimaryRd(String vpnName, TypedReadTransaction tx) throws ExecutionException, InterruptedException { - return tx.read(getVpnInstanceIdentifier(vpnName)).get().toJavaUtil().map(NatUtil::getPrimaryRd).orElse(null); + return tx.read(getVpnInstanceIdentifier(vpnName)).get().map(NatUtil::getPrimaryRd).orElse(null); } - public static String getPrimaryRd(DataBroker dataBroker, String vpnName) { - InstanceIdentifier id = getVpnInstanceIdentifier(vpnName); - Optional vpnInstance = - SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker, - LogicalDatastoreType.CONFIGURATION, id); - if (vpnInstance.isPresent()) { - return getPrimaryRd(vpnInstance.get()); - } - return vpnName; - } - - public static String getPrimaryRd(VpnInstance vpnInstance) { - List rds = null; - if (vpnInstance != null) { - rds = getListOfRdsFromVpnInstance(vpnInstance); + @Nullable + public static String getPrimaryRd(@Nullable VpnInstance vpnInstance) { + if (vpnInstance == null) { + return null; } - return rds == null || rds.isEmpty() ? vpnInstance.getVpnInstanceName() : rds.get(0); + List rds = getListOfRdsFromVpnInstance(vpnInstance); + return rds.isEmpty() ? vpnInstance.getVpnInstanceName() : rds.get(0); } public static InstanceIdentifier getVpnInstanceIdentifier(String vpnName) { @@ -2025,22 +2156,10 @@ public final class NatUtil { .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build(); } - @Nonnull + @NonNull public static List getListOfRdsFromVpnInstance(VpnInstance vpnInstance) { - VpnAfConfig vpnConfig = vpnInstance.getIpv4Family(); - return vpnConfig.getRouteDistinguisher() != null ? new ArrayList<>( - vpnConfig.getRouteDistinguisher()) : new ArrayList<>(); - } - - public static long getVpnIdFromExternalSubnet(DataBroker dataBroker, String routerName, String externalIpAddress) { - if (routerName != null) { - Routers extRouter = NatUtil.getRoutersFromConfigDS(dataBroker, routerName); - if (extRouter != null) { - return getExternalSubnetVpnIdForRouterExternalIp(dataBroker, externalIpAddress, extRouter); - } - } - - return NatConstants.INVALID_ID; + return vpnInstance.getRouteDistinguisher() != null ? new ArrayList<>( + vpnInstance.getRouteDistinguisher()) : new ArrayList<>(); } public static String validateAndAddNetworkMask(String ipAddress) { @@ -2053,27 +2172,26 @@ public final class NatUtil { new VpnInterfaceOpDataEntryKey(vpnInterfaceName, vpnName)).build(); } - public static VpnInstanceOpDataEntry getVpnInstanceOpData(DataBroker broker, String rd) { - InstanceIdentifier id = NatUtil.getVpnInstanceOpDataIdentifier(rd); - return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional( - broker, LogicalDatastoreType.OPERATIONAL, id).orNull(); - } - public static boolean checkForRoutersWithSameExtNetAndNaptSwitch(DataBroker broker, Uuid networkId, - String routerName, BigInteger dpnId) { + String routerName, Uint64 dpnId) { InstanceIdentifier id = buildNetworkIdentifier(networkId); - Optional networkData = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id); - + Optional networkData = null; + try { + networkData = SingleTransactionDataBroker.syncReadOptional(broker, + LogicalDatastoreType.CONFIGURATION, id); + } catch (ExecutionException | InterruptedException e) { + LOG.error("checkForRoutersWithSameExtNetAndNaptSwitch: Exception while reading Networks DS for the " + + "network {} router {} dpnId {}", networkId.getValue(), routerName, dpnId, e); + return false; + } if (networkData != null && networkData.isPresent()) { List routerUuidList = networkData.get().getRouterIds(); if (routerUuidList != null && !routerUuidList.isEmpty()) { for (Uuid routerUuid : routerUuidList) { String sharedRouterName = routerUuid.getValue(); if (!routerName.equals(sharedRouterName)) { - BigInteger switchDpnId = NatUtil.getPrimaryNaptfromRouterName(broker, sharedRouterName); - if (switchDpnId == null) { - continue; - } else if (switchDpnId.equals(dpnId)) { + Uint64 switchDpnId = NatUtil.getPrimaryNaptfromRouterName(broker, sharedRouterName); + if (switchDpnId != null && switchDpnId.equals(dpnId)) { LOG.debug("checkForRoutersWithSameExtNetAndNaptSwitch: external-network {} is " + "associated with other active router {} on NAPT switch {}", networkId, sharedRouterName, switchDpnId); @@ -2087,18 +2205,16 @@ public final class NatUtil { } public static boolean checkForRoutersWithSameExtSubnetAndNaptSwitch(DataBroker broker, Uuid externalSubnetId, - String routerName, BigInteger dpnId) { - List routerUuidList = getOptionalExternalSubnets(broker, externalSubnetId).toJavaUtil() - .map(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external - .subnets.Subnets::getRouterIds).orElse(Collections.emptyList()); - if (routerUuidList != null && !routerUuidList.isEmpty()) { + String routerName, Uint64 dpnId) { + List routerUuidList = getOptionalExternalSubnets(broker, externalSubnetId) + .map(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external + .subnets.Subnets::getRouterIds).orElse(emptyList()); + if (!routerUuidList.isEmpty()) { for (Uuid routerUuid : routerUuidList) { String sharedRouterName = routerUuid.getValue(); if (!routerName.equals(sharedRouterName)) { - BigInteger switchDpnId = NatUtil.getPrimaryNaptfromRouterName(broker, sharedRouterName); - if (switchDpnId == null) { - continue; - } else if (switchDpnId.equals(dpnId)) { + Uint64 switchDpnId = NatUtil.getPrimaryNaptfromRouterName(broker, sharedRouterName); + if (switchDpnId != null && switchDpnId.equals(dpnId)) { LOG.debug("checkForRoutersWithSameExtSubnetAndNaptSwitch: external-subnetwork {} is " + "associated with other active router {} on NAPT switch {}", externalSubnetId, sharedRouterName, switchDpnId); @@ -2111,19 +2227,19 @@ public final class NatUtil { } public static void installRouterGwFlows(ManagedNewTransactionRunner txRunner, IVpnManager vpnManager, - Routers router, BigInteger primarySwitchId, int addOrRemove) { - ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> { - List externalIps = router.getExternalIps(); + Routers router, Uint64 primarySwitchId, int addOrRemove) { + LoggingFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> { + Map keyExternalIpsMap = router.getExternalIps(); List externalIpsSting = new ArrayList<>(); - if (externalIps.isEmpty()) { + if (keyExternalIpsMap == null || keyExternalIpsMap.isEmpty()) { LOG.error("installRouterGwFlows: setupRouterGwFlows no externalIP present"); return; } - for (ExternalIps externalIp : externalIps) { + for (ExternalIps externalIp : keyExternalIpsMap.values()) { externalIpsSting.add(externalIp.getIpAddress()); } - Uuid subnetVpnName = externalIps.get(0).getSubnetId(); + Uuid subnetVpnName = keyExternalIpsMap.get(0).getSubnetId(); if (addOrRemove == NwConstants.ADD_FLOW) { vpnManager.addRouterGwMacFlow(router.getRouterName(), router.getExtGwMacAddress(), primarySwitchId, router.getNetworkId(), subnetVpnName.getValue(), tx); @@ -2140,6 +2256,205 @@ public final class NatUtil { }), LOG, "Error installing router gateway flows"); } + @SuppressWarnings("checkstyle:IllegalCatch") + public static void handleSNATForDPN(DataBroker dataBroker, IMdsalApiManager mdsalManager, + IdManagerService idManager, NaptSwitchHA naptSwitchHA, + Uint64 dpnId, Routers extRouters, Uint32 routerId, Uint32 routerVpnId, + TypedReadWriteTransaction confTx, + ProviderTypes extNwProvType, UpgradeState upgradeState) { + //Check if primary and secondary switch are selected, If not select the role + //Install select group to NAPT switch + //Install default miss entry to NAPT switch + Uint64 naptSwitch; + String routerName = extRouters.getRouterName(); + Boolean upgradeInProgress = false; + if (upgradeState != null) { + upgradeInProgress = upgradeState.isUpgradeInProgress(); + } + Uint64 naptId = NatUtil.getPrimaryNaptfromRouterName(dataBroker, routerName); + if (naptId == null || naptId.equals(Uint64.ZERO) + || (!NatUtil.getSwitchStatus(dataBroker, naptId) && (upgradeInProgress == false))) { + LOG.debug("handleSNATForDPN : NaptSwitch is down or not selected for router {},naptId {}", + routerName, naptId); + naptSwitch = dpnId; + boolean naptstatus = naptSwitchHA.updateNaptSwitch(routerName, naptSwitch); + if (!naptstatus) { + LOG.error("handleSNATForDPN : Failed to update newNaptSwitch {} for routername {}", + naptSwitch, routerName); + return; + } + LOG.debug("handleSNATForDPN : Switch {} is elected as NaptSwitch for router {}", dpnId, routerName); + + String externalVpnName = null; + NatUtil.createRouterIdsConfigDS(dataBroker, routerId, routerName); + naptSwitchHA.subnetRegisterMapping(extRouters, routerId); + Uuid extNwUuid = extRouters.getNetworkId(); + externalVpnName = NatUtil.getAssociatedVPN(dataBroker, extNwUuid); + if (externalVpnName != null) { + naptSwitchHA.installSnatFlows(routerName, routerId, naptSwitch, routerVpnId, extNwUuid, + externalVpnName, confTx); + } + // Install miss entry (table 26) pointing to table 46 + FlowEntity flowEntity = naptSwitchHA.buildSnatFlowEntityForNaptSwitch(dpnId, routerName, + routerVpnId, NatConstants.ADD_FLOW); + if (flowEntity == null) { + LOG.error("handleSNATForDPN : Failed to populate flowentity for router {} with dpnId {}", + routerName, dpnId); + return; + } + LOG.debug("handleSNATForDPN : Successfully installed flow for dpnId {} router {}", dpnId, routerName); + mdsalManager.addFlow(confTx, flowEntity); + //Removing primary flows from old napt switch + if (naptId != null && !naptId.equals(Uint64.ZERO)) { + LOG.debug("handleSNATForDPN : Removing primary flows from old napt switch {} for router {}", + naptId, routerName); + try { + naptSwitchHA.removeSnatFlowsInOldNaptSwitch(extRouters, routerId, naptId, null, + externalVpnName, confTx); + } catch (Exception e) { + LOG.error("Exception while removing SnatFlows form OldNaptSwitch {}", naptId, e); + } + } + naptSwitchHA.updateNaptSwitchBucketStatus(routerName, routerId, naptSwitch); + } else if (naptId.equals(dpnId)) { + LOG.error("handleSNATForDPN : NaptSwitch {} gone down during cluster reboot came alive", naptId); + } else { + naptSwitch = naptId; + LOG.debug("handleSNATForDPN : Napt switch with Id {} is already elected for router {}", + naptId, routerName); + + //installing group + List bucketInfo = naptSwitchHA.handleGroupInNeighborSwitches(dpnId, + routerName, routerId, naptSwitch); + naptSwitchHA.installSnatGroupEntry(dpnId, bucketInfo, routerName); + + // Install miss entry (table 26) pointing to group + Uint32 groupId = NatUtil.getUniqueId(idManager, NatConstants.SNAT_IDPOOL_NAME, + NatUtil.getGroupIdKey(routerName)); + if (groupId != NatConstants.INVALID_ID) { + FlowEntity flowEntity = + naptSwitchHA.buildSnatFlowEntity(dpnId, routerName, groupId.longValue(), + routerVpnId, NatConstants.ADD_FLOW); + if (flowEntity == null) { + LOG.error("handleSNATForDPN : Failed to populate flowentity for router {} with dpnId {}" + + " groupId {}", routerName, dpnId, groupId); + return; + } + LOG.debug("handleSNATForDPN : Successfully installed flow for dpnId {} router {} group {}", + dpnId, routerName, groupId); + mdsalManager.addFlow(confTx, flowEntity); + } else { + LOG.error("handleSNATForDPN: Unable to get groupId for router:{}", routerName); + } + } + } + + @SuppressWarnings("checkstyle:IllegalCatch") + public static void removeSNATFromDPN(DataBroker dataBroker, IMdsalApiManager mdsalManager, + IdManagerService idManager, NaptSwitchHA naptSwitchHA, Uint64 dpnId, + Routers extRouter, Uint32 routerId, Uint32 routerVpnId, String externalVpnName, + ProviderTypes extNwProvType, TypedReadWriteTransaction confTx) + throws ExecutionException, InterruptedException { + //irrespective of naptswitch or non-naptswitch, SNAT default miss entry need to be removed + //remove miss entry to NAPT switch + //if naptswitch elect new switch and install Snat flows and remove those flows in oldnaptswitch + if (extNwProvType == null) { + return; + } + String routerName = extRouter.getRouterName(); + //Get the external IP labels other than VXLAN provider type. Since label is not applicable for VXLAN + Map externalIpLabel; + if (extNwProvType == ProviderTypes.VXLAN) { + externalIpLabel = null; + } else { + externalIpLabel = NatUtil.getExternalIpsLabelForRouter(dataBroker, routerId); + } + Uint64 naptSwitch = NatUtil.getPrimaryNaptfromRouterName(dataBroker, routerName); + if (naptSwitch == null || naptSwitch.equals(Uint64.ZERO)) { + LOG.error("removeSNATFromDPN : No naptSwitch is selected for router {}", routerName); + return; + } + Collection externalIpCache = NatUtil.getExternalIpsForRouter(dataBroker, routerId); + boolean naptStatus = + naptSwitchHA.isNaptSwitchDown(extRouter, routerId, dpnId, naptSwitch, routerVpnId, + externalIpCache, confTx); + if (!naptStatus) { + LOG.debug("removeSNATFromDPN: Switch with DpnId {} is not naptSwitch for router {}", + dpnId, routerName); + Uint32 groupId = getUniqueId(idManager, NatConstants.SNAT_IDPOOL_NAME, NatUtil.getGroupIdKey(routerName)); + FlowEntity flowEntity = null; + try { + if (groupId != NatConstants.INVALID_ID) { + flowEntity = naptSwitchHA + .buildSnatFlowEntity(dpnId, routerName, groupId.longValue(), routerVpnId, + NatConstants.DEL_FLOW); + if (flowEntity == null) { + LOG.error("removeSNATFromDPN : Failed to populate flowentity for router:{} " + + "with dpnId:{} groupId:{}", routerName, dpnId, groupId); + return; + } + LOG.debug("removeSNATFromDPN : Removing default SNAT miss entry flow entity {}", + flowEntity); + mdsalManager.removeFlow(confTx, flowEntity); + } else { + LOG.error("removeSNATFromDPN: Unable to get groupId for router:{}", routerName); + } + + } catch (Exception ex) { + LOG.error("removeSNATFromDPN : Failed to remove default SNAT miss entry flow entity {}", + flowEntity, ex); + return; + } + LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routername {}", + dpnId, routerName); + + //remove group + GroupEntity groupEntity = null; + try { + if (groupId != NatConstants.INVALID_ID) { + groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId.longValue(), routerName, + GroupTypes.GroupAll, emptyList() /*listBucketInfo*/); + LOG.info("removeSNATFromDPN : Removing NAPT GroupEntity:{}", groupEntity); + mdsalManager.removeGroup(groupEntity); + } else { + LOG.error("removeSNATFromDPN: Unable to get groupId for router:{}", routerName); + } + } catch (Exception ex) { + LOG.error("removeSNATFromDPN : Failed to remove group entity {}", groupEntity, ex); + return; + } + LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routerName {}", + dpnId, routerName); + } else { + naptSwitchHA.removeSnatFlowsInOldNaptSwitch(extRouter, routerId, naptSwitch, + externalIpLabel, externalVpnName, confTx); + //remove table 26 flow ppointing to table46 + FlowEntity flowEntity = null; + try { + flowEntity = naptSwitchHA.buildSnatFlowEntityForNaptSwitch(dpnId, routerName, routerVpnId, + NatConstants.DEL_FLOW); + if (flowEntity == null) { + LOG.error("removeSNATFromDPN : Failed to populate flowentity for router {} with dpnId {}", + routerName, dpnId); + return; + } + LOG.debug("removeSNATFromDPN : Removing default SNAT miss entry flow entity for router {} with " + + "dpnId {} in napt switch {}", routerName, dpnId, naptSwitch); + mdsalManager.removeFlow(confTx, flowEntity); + + } catch (Exception ex) { + LOG.error("removeSNATFromDPN : Failed to remove default SNAT miss entry flow entity {}", + flowEntity, ex); + return; + } + LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routername {}", + dpnId, routerName); + + //best effort to check IntExt model + naptSwitchHA.bestEffortDeletion(routerId, routerName, externalIpLabel, confTx); + } + } + public static Boolean isOpenStackVniSemanticsEnforcedForGreAndVxlan(IElanService elanManager, ProviderTypes extNwProvType) { if (elanManager.isOpenStackVniSemanticsEnforced() && (extNwProvType == ProviderTypes.GRE @@ -2150,92 +2465,74 @@ public final class NatUtil { } public static void addPseudoPortToElanDpn(String elanInstanceName, String pseudoPortId, - BigInteger dpnId, DataBroker dataBroker) { + Uint64 dpnId, DataBroker dataBroker) { InstanceIdentifier elanDpnInterfaceId = getElanDpnInterfaceOperationalDataPath( - elanInstanceName,dpnId); + elanInstanceName, dpnId); + // FIXME: separate this out? + final ReentrantLock lock = JvmGlobalLocks.getLockForString(elanInstanceName); + lock.lock(); try { - synchronized (elanInstanceName.intern()) { - Optional dpnInElanInterfaces = SingleTransactionDataBroker.syncReadOptional(dataBroker, - LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId); - List elanInterfaceList; - DpnInterfaces dpnInterface; - if (!dpnInElanInterfaces.isPresent()) { - elanInterfaceList = new ArrayList<>(); - } else { - dpnInterface = dpnInElanInterfaces.get(); - elanInterfaceList = dpnInterface.getInterfaces(); - } - if (!elanInterfaceList.contains(pseudoPortId)) { - elanInterfaceList.add(pseudoPortId); - dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList) - .withKey(new DpnInterfacesKey(dpnId)).build(); - SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, - elanDpnInterfaceId, dpnInterface); - } + Optional dpnInElanInterfaces = SingleTransactionDataBroker.syncReadOptional(dataBroker, + LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId); + List elanInterfaceList = new ArrayList<>(); + DpnInterfaces dpnInterface; + if (dpnInElanInterfaces.isPresent()) { + dpnInterface = dpnInElanInterfaces.get(); + + elanInterfaceList = (dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) + ? new ArrayList<>(dpnInterface.getInterfaces()) : elanInterfaceList; } - } catch (ReadFailedException e) { + if (!elanInterfaceList.contains(pseudoPortId)) { + elanInterfaceList.add(pseudoPortId); + dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList) + .withKey(new DpnInterfacesKey(dpnId)).build(); + SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, + elanDpnInterfaceId, dpnInterface); + } + } catch (InterruptedException | ExecutionException e) { LOG.warn("Failed to read elanDpnInterface with error {}", e.getMessage()); } catch (TransactionCommitFailedException e) { LOG.warn("Failed to add elanDpnInterface with error {}", e.getMessage()); + } finally { + lock.unlock(); } } public static void removePseudoPortFromElanDpn(String elanInstanceName, String pseudoPortId, - BigInteger dpnId, DataBroker dataBroker) { + Uint64 dpnId, DataBroker dataBroker) { InstanceIdentifier elanDpnInterfaceId = getElanDpnInterfaceOperationalDataPath( - elanInstanceName,dpnId); + elanInstanceName, dpnId); + // FIXME: separate this out? + final ReentrantLock lock = JvmGlobalLocks.getLockForString(elanInstanceName); + lock.lock(); try { - synchronized (elanInstanceName.intern()) { - Optional dpnInElanInterfaces = SingleTransactionDataBroker.syncReadOptional(dataBroker, - LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId); - List elanInterfaceList; - DpnInterfaces dpnInterface; - if (!dpnInElanInterfaces.isPresent()) { - LOG.info("No interface in any dpn for {}", elanInstanceName); - return; - } else { - dpnInterface = dpnInElanInterfaces.get(); - elanInterfaceList = dpnInterface.getInterfaces(); - } - if (!elanInterfaceList.contains(pseudoPortId)) { - LOG.info("Router port not present in DPN {} for VPN {}", dpnId, elanInstanceName); - return; - } - elanInterfaceList.remove(pseudoPortId); - dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList) - .withKey(new DpnInterfacesKey(dpnId)).build(); - SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, - elanDpnInterfaceId, dpnInterface); + Optional dpnInElanInterfaces = SingleTransactionDataBroker.syncReadOptional(dataBroker, + LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId); + List elanInterfaceList = new ArrayList<>(); + DpnInterfaces dpnInterface; + if (!dpnInElanInterfaces.isPresent()) { + LOG.info("No interface in any dpn for {}", elanInstanceName); + return; } - } catch (ReadFailedException e) { + + dpnInterface = dpnInElanInterfaces.get(); + elanInterfaceList = (dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) + ? new ArrayList<>(dpnInterface.getInterfaces()) : elanInterfaceList; + if (!elanInterfaceList.contains(pseudoPortId)) { + LOG.info("Router port not present in DPN {} for VPN {}", dpnId, elanInstanceName); + return; + } + elanInterfaceList.remove(pseudoPortId); + dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList) + .withKey(new DpnInterfacesKey(dpnId)).build(); + SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, + elanDpnInterfaceId, dpnInterface); + } catch (InterruptedException | ExecutionException e) { LOG.warn("Failed to read elanDpnInterface with error {}", e.getMessage()); } catch (TransactionCommitFailedException e) { LOG.warn("Failed to remove elanDpnInterface with error {}", e.getMessage()); - } - - } - - public static DpnInterfaces getElanInterfaceInfoByElanDpn(String elanInstanceName, BigInteger dpId, - DataBroker broker) { - InstanceIdentifier elanDpnInterfacesId = - getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId); - DpnInterfaces dpnInterfaces = null; - try { - dpnInterfaces = SingleTransactionDataBroker.syncRead(broker, LogicalDatastoreType.OPERATIONAL, - elanDpnInterfacesId); - } - catch (ReadFailedException e) { - LOG.warn("Failed to read ElanDpnInterfacesList with error {}", e.getMessage()); - } - return dpnInterfaces; - } - - 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); + } finally { + lock.unlock(); } } @@ -2250,23 +2547,16 @@ public final class NatUtil { return true; } - public static InstanceIdentifier buildExtRouters() { - InstanceIdentifier extRouterInstanceIndentifier = InstanceIdentifier.builder(ExtRouters.class) - .build(); - return extRouterInstanceIndentifier; - } - + @Nullable public static LearntVpnVipToPortData getLearntVpnVipToPortData(DataBroker dataBroker) { - InstanceIdentifier learntVpnVipToPortDataId = getLearntVpnVipToPortDataId(); - LearntVpnVipToPortData learntVpnVipToPortData = null; try { - learntVpnVipToPortData = SingleTransactionDataBroker.syncRead(dataBroker, - LogicalDatastoreType.OPERATIONAL, learntVpnVipToPortDataId); + return SingleTransactionDataBroker.syncRead(dataBroker, + LogicalDatastoreType.OPERATIONAL, getLearntVpnVipToPortDataId()); } - catch (ReadFailedException e) { + catch (ExpectedDataObjectNotFoundException e) { LOG.warn("Failed to read LearntVpnVipToPortData with error {}", e.getMessage()); + return null; } - return learntVpnVipToPortData; } public static InstanceIdentifier getLearntVpnVipToPortDataId() { @@ -2276,12 +2566,18 @@ public final class NatUtil { } public static InstanceIdentifier getElanDpnInterfaceOperationalDataPath(String elanInstanceName, - BigInteger dpId) { + Uint64 dpId) { return InstanceIdentifier.builder(ElanDpnInterfaces.class) .child(ElanDpnInterfacesList.class, new ElanDpnInterfacesListKey(elanInstanceName)) .child(DpnInterfaces.class, new DpnInterfacesKey(dpId)).build(); } + public static InstanceIdentifier getGroupInstanceId(Uint64 dpnId, Uint32 groupId) { + return InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight + .inventory.rev130819.nodes.Node.class, new NodeKey(new NodeId("openflow:" + dpnId))) + .augmentation(FlowCapableNode.class).child(Group.class, new GroupKey(new GroupId(groupId))).build(); + } + public static void createGroupIdPool(IdManagerService idManager) { CreateIdPoolInput createPool = new CreateIdPoolInputBuilder() .setPoolName(NatConstants.SNAT_IDPOOL_NAME) @@ -2299,4 +2595,402 @@ public final class NatUtil { LOG.error("createGroupIdPool : Failed to create PortPool for NAPT Service", e); } } + + public static boolean getSwitchStatus(DataBroker broker, Uint64 switchId) { + NodeId nodeId = new NodeId("openflow:" + switchId); + LOG.debug("getSwitchStatus : Querying switch with dpnId {} is up/down", nodeId); + InstanceIdentifier nodeInstanceId + = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight + .inventory.rev130819.nodes.Node.class, new NodeKey(nodeId)).build(); + Optional nodeOptional = + SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, + LogicalDatastoreType.OPERATIONAL, nodeInstanceId); + if (nodeOptional.isPresent()) { + LOG.debug("getSwitchStatus : Switch {} is up", nodeId); + return true; + } + LOG.debug("getSwitchStatus : Switch {} is down", nodeId); + return false; + } + + public static boolean isExternalNetwork(DataBroker broker, Uuid networkId) { + InstanceIdentifier id = buildNetworkIdentifier(networkId); + Optional networkData = + SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional( + broker, LogicalDatastoreType.CONFIGURATION, id); + return networkData.isPresent(); + } + + @Nullable + public static String getElanInstancePhysicalNetwok(String elanInstanceName, DataBroker broker) { + ElanInstance elanInstance = getElanInstanceByName(elanInstanceName, broker); + if (null != elanInstance) { + return elanInstance.getPhysicalNetworkName(); + } + return null; + + } + + public static Map getOpenvswitchOtherConfigMap(Uint64 dpnId, DataBroker dataBroker) { + String otherConfigVal = getProviderMappings(dpnId, dataBroker); + return getMultiValueMap(otherConfigVal); + } + + public static Map getMultiValueMap(String multiKeyValueStr) { + if (Strings.isNullOrEmpty(multiKeyValueStr)) { + return Collections.emptyMap(); + } + + Map valueMap = new HashMap<>(); + Splitter splitter = Splitter.on(OTHER_CONFIG_PARAMETERS_DELIMITER); + for (String keyValue : splitter.split(multiKeyValueStr)) { + String[] split = keyValue.split(OTHER_CONFIG_KEY_VALUE_DELIMITER, 2); + if (split.length == 2) { + valueMap.put(split[0], split[1]); + } + } + + return valueMap; + } + + public static Optional getBridgeRefInfo(Uint64 dpnId, DataBroker dataBroker) { + InstanceIdentifier bridgeRefInfoPath = InstanceIdentifier.create(BridgeRefInfo.class) + .child(BridgeRefEntry.class, new BridgeRefEntryKey(dpnId)); + + Optional bridgeRefEntry = + SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker, + LogicalDatastoreType.OPERATIONAL, bridgeRefInfoPath); + if (!bridgeRefEntry.isPresent()) { + LOG.info("getBridgeRefInfo : bridgeRefEntry is not present for {}", dpnId); + return Optional.empty(); + } + + InstanceIdentifier nodeId = + bridgeRefEntry.get().getBridgeReference().getValue().firstIdentifierOf(Node.class); + + return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker, + LogicalDatastoreType.OPERATIONAL, nodeId); + } + + @Nullable + public static String getProviderMappings(Uint64 dpId, DataBroker dataBroker) { + return getBridgeRefInfo(dpId, dataBroker).map(node -> getOpenvswitchOtherConfigs(node, + PROVIDER_MAPPINGS, dataBroker)).orElse(null); + } + + @Nullable + public static String getOpenvswitchOtherConfigs(Node node, String key, DataBroker dataBroker) { + OvsdbNodeAugmentation ovsdbNode = node.augmentation(OvsdbNodeAugmentation.class); + if (ovsdbNode == null) { + Optional nodeFromReadOvsdbNode = readOvsdbNode(node, dataBroker); + if (nodeFromReadOvsdbNode.isPresent()) { + ovsdbNode = nodeFromReadOvsdbNode.get().augmentation(OvsdbNodeAugmentation.class); + } + } + + if (ovsdbNode != null && ovsdbNode.getOpenvswitchOtherConfigs() != null) { + for (OpenvswitchOtherConfigs openvswitchOtherConfigs + : ovsdbNode.nonnullOpenvswitchOtherConfigs().values()) { + if (Objects.equals(openvswitchOtherConfigs.getOtherConfigKey(), key)) { + return openvswitchOtherConfigs.getOtherConfigValue(); + } + } + } + LOG.info("getOpenvswitchOtherConfigs : OtherConfigs is not present for ovsdbNode {}", node.getNodeId()); + return null; + } + + @NonNull + public static Optional readOvsdbNode(Node bridgeNode, DataBroker dataBroker) { + OvsdbBridgeAugmentation bridgeAugmentation = extractBridgeAugmentation(bridgeNode); + if (bridgeAugmentation != null) { + InstanceIdentifier ovsdbNodeIid = + (InstanceIdentifier) bridgeAugmentation.getManagedBy().getValue(); + return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker, + LogicalDatastoreType.OPERATIONAL, ovsdbNodeIid); + } + return Optional.empty(); + + } + + @Nullable + public static OvsdbBridgeAugmentation extractBridgeAugmentation(Node node) { + if (node == null) { + return null; + } + return node.augmentation(OvsdbBridgeAugmentation.class); + } + + public static String getDefaultFibRouteToSNATForSubnetJobKey(String subnetName, Uint64 dpnId) { + return NatConstants.NAT_DJC_PREFIX + subnetName + dpnId; + } + + public static ExternalSubnets getExternalSubnets(DataBroker dataBroker) { + InstanceIdentifier subnetsIdentifier = + InstanceIdentifier.builder(ExternalSubnets.class) + .build(); + try { + Optional optionalExternalSubnets = SingleTransactionDataBroker + .syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier); + if (optionalExternalSubnets.isPresent()) { + return optionalExternalSubnets.get(); + } + } catch (InterruptedException | ExecutionException e) { + LOG.error("Failed to read the subnets from the datastore."); + } + return null; + + } + + public static void addFlow(TypedWriteTransaction confTx, IMdsalApiManager mdsalManager, + Uint64 dpId, short tableId, String flowId, int priority, String flowName, Uint64 cookie, + List matches, List instructions) { + FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, flowId, priority, flowName, + NatConstants.DEFAULT_IDLE_TIMEOUT, NatConstants.DEFAULT_IDLE_TIMEOUT, cookie, matches, + instructions); + LOG.trace("syncFlow : Installing DpnId {}, flowId {}", dpId, flowId); + mdsalManager.addFlow(confTx, flowEntity); + } + + public static void removeFlow(TypedReadWriteTransaction confTx, IMdsalApiManager mdsalManager, + Uint64 dpId, short tableId, String flowId) throws ExecutionException, InterruptedException { + LOG.trace("syncFlow : Removing Acl Flow DpnId {}, flowId {}", dpId, flowId); + mdsalManager.removeFlow(confTx, dpId, flowId, tableId); + } + + public static String getIpv6FlowRef(Uint64 dpnId, short tableId, Uint32 routerID) { + return new StringBuilder().append(NatConstants.IPV6_FLOWID_PREFIX).append(dpnId).append(NatConstants + .FLOWID_SEPARATOR).append(tableId).append(NatConstants.FLOWID_SEPARATOR).append(routerID).toString(); + } + + public static String getTunnelInterfaceName(Uint64 srcDpId, Uint64 dstDpId, + ItmRpcService itmManager) { + Class tunType = TunnelTypeVxlan.class; + RpcResult rpcResult; + try { + Future> result = itmManager + .getTunnelInterfaceName(new GetTunnelInterfaceNameInputBuilder().setSourceDpid(srcDpId) + .setDestinationDpid(dstDpId).setTunnelType(tunType).build()); + rpcResult = result.get(); + if (!rpcResult.isSuccessful()) { + tunType = TunnelTypeGre.class ; + result = itmManager.getTunnelInterfaceName(new GetTunnelInterfaceNameInputBuilder() + .setSourceDpid(srcDpId) + .setDestinationDpid(dstDpId) + .setTunnelType(tunType) + .build()); + rpcResult = result.get(); + if (!rpcResult.isSuccessful()) { + LOG.warn("getTunnelInterfaceName : RPC Call to getTunnelInterfaceId returned with Errors {}", + rpcResult.getErrors()); + } else { + return rpcResult.getResult().getInterfaceName(); + } + LOG.warn("getTunnelInterfaceName : RPC Call to getTunnelInterfaceId returned with Errors {}", + rpcResult.getErrors()); + } else { + return rpcResult.getResult().getInterfaceName(); + } + } catch (InterruptedException | ExecutionException | NullPointerException e) { + LOG.error("getTunnelInterfaceName : Exception when getting tunnel interface Id for tunnel " + + "between {} and {}", srcDpId, dstDpId); + } + return null; + } + + public static Boolean isRouterInterfacePort(DataBroker broker, String ifaceName) { + Port neutronPort = getNeutronPort(broker, ifaceName); + if (neutronPort == null) { + return Boolean.TRUE; + } else { + return (NatConstants.NETWORK_ROUTER_INTERFACE.equalsIgnoreCase(neutronPort.getDeviceOwner()) ? Boolean.TRUE + : Boolean.FALSE); + } + } + + private static Port getNeutronPort(DataBroker broker, String ifaceName) { + InstanceIdentifier + portsIdentifier = InstanceIdentifier.create(Neutron.class) + .child( + org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports.class) + .child(Port.class, new PortKey(new Uuid(ifaceName))); + Optional portsOptional; + try { + portsOptional = SingleTransactionDataBroker + .syncReadOptional(broker, LogicalDatastoreType.CONFIGURATION, portsIdentifier); + } catch (InterruptedException | ExecutionException e) { + LOG.error("Read Failed Exception While Reading Neutron Port for {}", ifaceName, e); + portsOptional = Optional.empty(); + } + if (!portsOptional.isPresent()) { + LOG.error("getNeutronPort : No neutron ports found for interface {}", ifaceName); + return null; + } + return portsOptional.get(); + } + + public static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn + .instance.to.vpn.id.VpnInstance getVpnIdToVpnInstance(DataBroker broker, String vpnName) { + if (vpnName == null) { + return null; + } + + InstanceIdentifier id = getVpnInstanceToVpnIdIdentifier(vpnName); + Optional vpnInstance = Optional.empty(); + try { + vpnInstance = SingleTransactionDataBroker.syncReadOptional(broker, LogicalDatastoreType.CONFIGURATION, id); + } catch (InterruptedException | ExecutionException e) { + LOG.error("Failed to read VpnInstance {}", vpnInstance, e); + } + if (vpnInstance.isPresent()) { + return vpnInstance.get(); + } else { + return null; + } + } + + public static Uint32 getExternalVpnIdForExtNetwork(DataBroker broker, Uuid externalNwUuid) { + //Get the VPN ID from the ExternalNetworks model + if (externalNwUuid == null) { + LOG.error("getExternalVpnIdForExtNetwork : externalNwUuid is null"); + return null; + } + Uuid vpnUuid = getVpnIdfromNetworkId(broker, externalNwUuid); + if (vpnUuid == null) { + LOG.error("NAT Service : vpnUuid is null"); + return null; + } + Uint32 vpnId = getVpnId(broker, vpnUuid.getValue()); + return vpnId; + } + + static ReentrantLock lockForNat(final Uint64 dataPath) { + // FIXME: wrap this in an Identifier + return JvmGlobalLocks.getLockForString(NatConstants.NAT_DJC_PREFIX + dataPath); + } + + public static void removeSnatEntriesForPort(DataBroker dataBroker, NaptManager naptManager, + IMdsalApiManager mdsalManager, NeutronvpnService neutronVpnService, + String interfaceName, String routerName) { + Uint32 routerId = NatUtil.getVpnId(dataBroker, routerName); + if (routerId == NatConstants.INVALID_ID) { + LOG.error("removeSnatEntriesForPort: routerId not found for routername {}", routerName); + return; + } + Uint64 naptSwitch = getPrimaryNaptfromRouterName(dataBroker, routerName); + if (naptSwitch == null || naptSwitch.equals(Uint64.ZERO)) { + LOG.error("removeSnatEntriesForPort: NaptSwitch is not elected for router {}" + + "with Id {}", routerName, routerId); + return; + } + //getInternalIp for port + List fixedIps = getFixedIpsForPort(neutronVpnService, interfaceName); + if (fixedIps == null) { + LOG.error("removeSnatEntriesForPort: Internal Ips not found for InterfaceName {} in router {} with id {}", + interfaceName, routerName, routerId); + return; + } + List protocolTypesList = getPortocolList(); + for (String internalIp : fixedIps) { + LOG.debug("removeSnatEntriesForPort: Internal Ip retrieved for interface {} is {} in router with Id {}", + interfaceName, internalIp, routerId); + for (ProtocolTypes protocol : protocolTypesList) { + List portList = NatUtil.getInternalIpPortListInfo(dataBroker, routerId, internalIp, protocol); + if (portList != null) { + for (Uint16 portnum : portList) { + //build and remove the flow in outbound table + removeNatFlow(mdsalManager, naptSwitch, NwConstants.OUTBOUND_NAPT_TABLE, + routerId, internalIp, portnum.toJava(), protocol.getName()); + + //build and remove the flow in inboundtable + + removeNatFlow(mdsalManager, naptSwitch, NwConstants.INBOUND_NAPT_TABLE, routerId, + internalIp, portnum.toJava(), protocol.getName()); + + //Get the external IP address and the port from the model + + NAPTEntryEvent.Protocol proto = protocol.toString().equals(ProtocolTypes.TCP.toString()) + ? NAPTEntryEvent.Protocol.TCP : NAPTEntryEvent.Protocol.UDP; + IpPortExternal ipPortExternal = NatUtil.getExternalIpPortMap(dataBroker, routerId, + internalIp, String.valueOf(portnum.toJava()), proto); + if (ipPortExternal == null) { + LOG.error("removeSnatEntriesForPort: Mapping for internalIp {} " + + "with port {} is not found in " + + "router with Id {}", internalIp, portnum, routerId); + return; + } + String externalIpAddress = ipPortExternal.getIpAddress(); + String internalIpPort = internalIp + ":" + portnum.toJava(); + // delete the entry from IntExtIpPortMap DS + + naptManager.removeFromIpPortMapDS(routerId, internalIpPort, proto); + naptManager.removePortFromPool(internalIpPort, externalIpAddress); + + } + } else { + LOG.debug("removeSnatEntriesForPort: No {} session for interface {} with internalIP {} " + + "in router with id {}", + protocol, interfaceName, internalIp, routerId); + } + } + // delete the entry from SnatIntIpPortMap DS + LOG.debug("removeSnatEntriesForPort: Removing InternalIp :{} of router {} from snatint-ip-port-map", + internalIp, routerId); + naptManager.removeFromSnatIpPortDS(routerId, internalIp); + } + } + + private static List getFixedIpsForPort(NeutronvpnService neutronVpnService, String interfname) { + LOG.debug("getFixedIpsForPort: getFixedIpsForPort method is called for interface {}", interfname); + try { + Future> result = + neutronVpnService.getFixedIPsForNeutronPort(new GetFixedIPsForNeutronPortInputBuilder() + .setPortId(new Uuid(interfname)).build()); + + RpcResult rpcResult = result.get(); + if (!rpcResult.isSuccessful()) { + LOG.error("getFixedIpsForPort: RPC Call to GetFixedIPsForNeutronPortOutput returned with Errors {}", + rpcResult.getErrors()); + } else { + return rpcResult.getResult().getFixedIPs(); + } + } catch (InterruptedException | ExecutionException | NullPointerException ex) { + LOG.error("getFixedIpsForPort: Exception while receiving fixedIps for port {}", interfname, ex); + } + return null; + } + + private static List getPortocolList() { + List protocollist = new ArrayList<>(); + protocollist.add(ProtocolTypes.TCP); + protocollist.add(ProtocolTypes.UDP); + return protocollist; + } + + private static void removeNatFlow(IMdsalApiManager mdsalManager, Uint64 dpnId, short tableId, Uint32 routerId, + String ipAddress, int ipPort, String protocol) { + + String switchFlowRef = NatUtil.getNaptFlowRef(dpnId, tableId, String.valueOf(routerId), ipAddress, ipPort, + protocol); + FlowEntity snatFlowEntity = NatUtil.buildFlowEntity(dpnId, tableId, switchFlowRef); + + mdsalManager.removeFlow(snatFlowEntity); + LOG.debug("removeNatFlow: Removed the flow in table {} for the switch with the DPN ID {} for " + + "router {} ip {} port {}", tableId, dpnId, routerId, ipAddress, ipPort); + } + + public static String getDpnFromNodeRef(NodeRef node) { + PathArgument pathArgument = Iterables.get(node.getValue().getPathArguments(), 1); + InstanceIdentifier.IdentifiableItem item = Arguments.checkInstanceOf(pathArgument, + InstanceIdentifier.IdentifiableItem.class); + NodeKey key = Arguments.checkInstanceOf(item.getKey(), NodeKey.class); + String dpnKey = key.getId().getValue(); + String dpnID = null; + if (dpnKey.contains(NatConstants.COLON_SEPARATOR)) { + dpnID = Uint64.valueOf(dpnKey.split(NatConstants.COLON_SEPARATOR)[1]).toString(); + } + return dpnID; + } }