/* * Copyright © 2016, 2017 Ericsson India Global Services Pvt Ltd. and others. All rights reserved. * * This program and the accompanying materials are made available under the * 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 com.google.common.base.Optional; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import java.math.BigInteger; import java.net.InetAddress; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.genius.mdsalutil.ActionInfo; import org.opendaylight.genius.mdsalutil.FlowEntity; import org.opendaylight.genius.mdsalutil.MDSALUtil; import org.opendaylight.genius.mdsalutil.MatchInfo; import org.opendaylight.genius.mdsalutil.NwConstants; import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit; import org.opendaylight.genius.mdsalutil.actions.ActionOutput; import org.opendaylight.genius.mdsalutil.actions.ActionPushVlan; import org.opendaylight.genius.mdsalutil.actions.ActionRegLoad; import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldVlanVid; import org.opendaylight.netvirt.bgpmanager.api.IBgpManager; import org.opendaylight.netvirt.fibmanager.api.IFibManager; import org.opendaylight.netvirt.fibmanager.api.RouteOrigin; import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants; 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.interfaces.VpnInterface; import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey; 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.interfaces.rev140508.Interfaces; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; 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.genius.idmanager.rev160406.AllocateIdInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.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; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey; 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.inventory.rev130819.NodeConnectorId; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.DpnRouters; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.LearntVpnVipToPortData; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.NeutronRouterDpns; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnIdToVpnInstance; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceOpData; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersList; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersList; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPortKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnList; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesList; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIdsKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey; 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; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpPortInfo; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpMap; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpPortMap; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.NaptSwitches; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProtocolTypes; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterIdName; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterToVpnMapping; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.SnatintIpPortMap; 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.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; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMap; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMapKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMapping; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMappingKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.ip.mapping.IpMap; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMapping; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMappingKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolType; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolTypeKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMap; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMapKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.ip.port.map.IpPortExternal; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitch; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitchKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIds; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.Routermapping; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.RoutermappingKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMap; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMapKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPort; 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.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.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.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.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.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; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6; 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.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class NatUtil { private static String OF_URI_SEPARATOR = ":"; private static final Logger LOG = LoggerFactory.getLogger(NatUtil.class); /* 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)); } /* 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)); } /* getVpnId() returns the VPN ID from the VPN name */ public static long getVpnId(DataBroker broker, String vpnName) { if (vpnName == null) { return NatConstants.INVALID_ID; } InstanceIdentifier id = getVpnInstanceToVpnIdIdentifier(vpnName); Optional vpnInstance = read(broker, LogicalDatastoreType.CONFIGURATION, id); long vpnId = NatConstants.INVALID_ID; if (vpnInstance.isPresent()) { Long vpnIdAsLong = vpnInstance.get().getVpnId(); if (vpnIdAsLong != null) { vpnId = vpnIdAsLong; } } return vpnId; } public static Long getVpnId(DataBroker broker, long routerId) { //Get the external network ID from the ExternalRouter model Uuid networkId = NatUtil.getNetworkIdFromRouterId(broker, routerId); if (networkId == null) { LOG.error("NAT Service : networkId is null"); return null; } //Get the VPN ID from the ExternalNetworks model Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(broker, networkId); if (vpnUuid == null) { LOG.error("NAT Service : vpnUuid is null"); return null; } Long vpnId = NatUtil.getVpnId(broker, vpnUuid.getValue()); return vpnId; } static InstanceIdentifier getRouterPortsId(String routerId) { return InstanceIdentifier.builder(FloatingIpInfo.class) .child(RouterPorts.class, new RouterPortsKey(routerId)).build(); } static InstanceIdentifier getRouterVpnMappingId(String routerId) { return InstanceIdentifier.builder(RouterToVpnMapping.class) .child(Routermapping.class, new RoutermappingKey(routerId)).build(); } static InstanceIdentifier getPortsIdentifier(String routerId, String portName) { return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId)) .child(Ports.class, new PortsKey(portName)).build(); } static InstanceIdentifier getIntExtPortMapIdentifier(String routerId, String portName, String internalIp) { return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId)) .child(Ports.class, new PortsKey(portName)) .child(InternalToExternalPortMap.class, new InternalToExternalPortMapKey(internalIp)).build(); } static InstanceIdentifier getVpnInstanceToVpnIdIdentifier(String vpnName) { return InstanceIdentifier.builder(VpnInstanceToVpnId.class) .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn .instance.to.vpn.id.VpnInstance.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn .instance.to.vpn.id.VpnInstanceKey(vpnName)).build(); } static String getVpnInstanceFromVpnIdentifier(DataBroker broker, long vpnId) { InstanceIdentifier id = InstanceIdentifier.builder(VpnIdToVpnInstance.class) .child(VpnIds.class, new VpnIdsKey(vpnId)).build(); Optional vpnInstance = read(broker, LogicalDatastoreType.CONFIGURATION, id); return vpnInstance.isPresent() ? vpnInstance.get().getVpnInstanceName() : 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(BigInteger dpnId, short tableId, InetAddress destPrefix) { return NatConstants.FLOWID_PREFIX + dpnId + NwConstants.FLOWID_SEPARATOR + tableId + NwConstants .FLOWID_SEPARATOR + destPrefix.getHostAddress(); } 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; } /* getNetworkIdFromRouterId() returns the network-id from the below model using the router-id as the key container ext-routers { list routers { key router-name; leaf router-name { type string; } leaf network-id { type yang:uuid; } leaf enable-snat { type boolean; } leaf-list external-ips { type string; //format - ipaddress\prefixlength } leaf-list subnet-ids { type yang:uuid; } } } */ static Uuid getNetworkIdFromRouterId(DataBroker broker, long routerId) { String routerName = getRouterName(broker, routerId); return getNetworkIdFromRouterName(broker, routerName); } static Uuid getNetworkIdFromRouterName(DataBroker broker, String routerName) { if (routerName == null) { LOG.error("getNetworkIdFromRouterName - empty routerName received"); return null; } InstanceIdentifier id = buildRouterIdentifier(routerName); Optional routerData = read(broker, LogicalDatastoreType.CONFIGURATION, id); if (routerData.isPresent()) { return routerData.get().getNetworkId(); } return null; } static InstanceIdentifier buildRouterIdentifier(String routerId) { InstanceIdentifier routerInstanceIndentifier = InstanceIdentifier.builder(ExtRouters.class) .child(Routers.class, new RoutersKey(routerId)).build(); return routerInstanceIndentifier; } private static InstanceIdentifier buildRouterIdentifier(Long routerId) { InstanceIdentifier routerIds = InstanceIdentifier.builder(RouterIdName.class) .child(RouterIds.class, new RouterIdsKey(routerId)).build(); return routerIds; } /** * Return if SNAT is enabled for the given router. * * @param broker The DataBroker * @param routerId The router * @return boolean true if enabled, otherwise false */ static boolean isSnatEnabledForRouterId(DataBroker broker, String routerId) { InstanceIdentifier id = buildRouterIdentifier(routerId); Optional routerData = read(broker, LogicalDatastoreType.CONFIGURATION, id); if (routerData.isPresent()) { return routerData.get().isEnableSnat(); } return false; } /* getVpnIdfromNetworkId() returns the vpnid from the below model using the network ID as the key. container external-networks { list networks { key id; leaf id { type yang:uuid; } leaf vpnid { type yang:uuid; } leaf-list router-ids { type yang:uuid; } leaf-list subnet-ids{ type yang:uuid; } } } */ public static Uuid getVpnIdfromNetworkId(DataBroker broker, Uuid networkId) { InstanceIdentifier id = buildNetworkIdentifier(networkId); Optional networkData = read(broker, LogicalDatastoreType.CONFIGURATION, id); if (networkData.isPresent()) { return networkData.get().getVpnid(); } return null; } public static ProviderTypes getProviderTypefromNetworkId(DataBroker broker, Uuid networkId) { InstanceIdentifier id = buildNetworkIdentifier(networkId); Optional networkData = read(broker, LogicalDatastoreType.CONFIGURATION, id); if ((networkData.isPresent()) && (networkData.get() != null)) { return networkData.get().getProviderNetworkType(); } return null; } public static List getRouterIdsfromNetworkId(DataBroker broker, Uuid networkId) { InstanceIdentifier id = buildNetworkIdentifier(networkId); Optional networkData = read(broker, LogicalDatastoreType.CONFIGURATION, id); return networkData.isPresent() ? networkData.get().getRouterIds() : Collections.emptyList(); } static String getAssociatedExternalNetwork(DataBroker dataBroker, String routerId) { InstanceIdentifier id = NatUtil.buildRouterIdentifier(routerId); Optional routerData = NatUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id); if (routerData.isPresent()) { Uuid networkId = routerData.get().getNetworkId(); if (networkId != null) { return networkId.getValue(); } } return null; } private static InstanceIdentifier buildNetworkIdentifier(Uuid networkId) { InstanceIdentifier network = InstanceIdentifier.builder(ExternalNetworks.class) .child(Networks.class, new NetworksKey(networkId)).build(); return network; } /* getNaptSwitchesDpnIdsfromRouterId() returns the primary-switch-id and the secondary-switch-id in a array using the router-id; as the key. container napt-switches { list router-to-napt-switch { key router-id; leaf router-id { type uint32; } leaf primary-switch-id { type uint64; } leaf secondary-switch-id { type uint64; } } } */ public static BigInteger getPrimaryNaptfromRouterId(DataBroker broker, Long routerId) { // convert routerId to Name String routerName = getRouterName(broker, routerId); return getPrimaryNaptfromRouterName(broker, routerName); } public static BigInteger getPrimaryNaptfromRouterName(DataBroker broker, String routerName) { if (routerName == null) { LOG.error("getPrimaryNaptfromRouterName - empty routerName received"); return null; } InstanceIdentifier id = buildNaptSwitchIdentifier(routerName); Optional routerToNaptSwitchData = read(broker, LogicalDatastoreType.CONFIGURATION, id); if (routerToNaptSwitchData.isPresent()) { RouterToNaptSwitch routerToNaptSwitchInstance = routerToNaptSwitchData.get(); return routerToNaptSwitchInstance.getPrimarySwitchId(); } return null; } private static InstanceIdentifier buildNaptSwitchIdentifier(String routerId) { InstanceIdentifier rtrNaptSw = InstanceIdentifier.builder(NaptSwitches.class) .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId)).build(); return rtrNaptSw; } public static String getRouterName(DataBroker broker, Long routerId) { InstanceIdentifier id = buildRouterIdentifier(routerId); Optional routerIdsData = read(broker, LogicalDatastoreType.CONFIGURATION, id); if (routerIdsData.isPresent()) { RouterIds routerIdsInstance = routerIdsData.get(); return routerIdsInstance.getRouterName(); } return null; } // TODO Clean up the exception handling @SuppressWarnings("checkstyle:IllegalCatch") public static Optional read(DataBroker broker, LogicalDatastoreType datastoreType, InstanceIdentifier path) { ReadOnlyTransaction tx = broker.newReadOnlyTransaction(); try { return tx.read(datastoreType, path).get(); } catch (Exception e) { throw new RuntimeException(e); } } static InstanceIdentifier getVpnInstanceOpDataIdentifier(String vrfId) { return InstanceIdentifier.builder(VpnInstanceOpData.class) .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vrfId)).build(); } public static long readVpnId(DataBroker broker, String vpnName) { InstanceIdentifier id = getVpnInstanceToVpnIdIdentifier(vpnName); Optional vpnInstance = read(broker, LogicalDatastoreType.CONFIGURATION, id); long vpnId = NatConstants.INVALID_ID; if (vpnInstance.isPresent()) { vpnId = vpnInstance.get().getVpnId(); } return vpnId; } public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, BigInteger cookie) { FlowEntity flowEntity = new FlowEntity(dpnId); flowEntity.setTableId(tableId); flowEntity.setCookie(cookie); return flowEntity; } public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId, int priority, String flowName, BigInteger cookie, List listMatchInfo) { FlowEntity flowEntity = new FlowEntity(dpnId); flowEntity.setTableId(tableId); flowEntity.setFlowId(flowId); flowEntity.setPriority(priority); flowEntity.setFlowName(flowName); flowEntity.setCookie(cookie); flowEntity.setMatchInfoList(listMatchInfo); return flowEntity; } public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, BigInteger cookie, String flowId) { FlowEntity flowEntity = new FlowEntity(dpnId); flowEntity.setTableId(tableId); flowEntity.setCookie(cookie); flowEntity.setFlowId(flowId); return flowEntity; } public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId) { FlowEntity flowEntity = new FlowEntity(dpnId); flowEntity.setTableId(tableId); flowEntity.setFlowId(flowId); return flowEntity; } 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) { String nextHopIp = null; InstanceIdentifier tunnelInfoId = InstanceIdentifier.builder(DpnEndpoints.class) .child(DPNTEPsInfo.class, new DPNTEPsInfoKey(dpnId)).build(); Optional tunnelInfo = read(broker, LogicalDatastoreType.CONFIGURATION, tunnelInfoId); if (tunnelInfo.isPresent()) { List nexthopIpList = tunnelInfo.get().getTunnelEndPoints(); if (nexthopIpList != null && !nexthopIpList.isEmpty()) { nextHopIp = nexthopIpList.get(0).getIpAddress().getIpv4Address().getValue(); } } return nextHopIp; } /* getVpnRd returns the rd (route distinguisher) which is the VRF ID from the below model using the vpnName list vpn-instance { key "vpn-instance-name" leaf vpn-instance-name { type string; } leaf vpn-id { type uint32; } leaf vrf-id { type string; } } */ public static String getVpnRd(DataBroker broker, String vpnName) { InstanceIdentifier id = getVpnInstanceToVpnIdIdentifier(vpnName); Optional vpnInstance = read(broker, LogicalDatastoreType.CONFIGURATION, id); String rd = null; if (vpnInstance.isPresent()) { rd = vpnInstance.get().getVrfId(); } return rd; } /* getExternalIPPortMap() returns the internal IP and the port for the querried router ID, external IP and the port. container intext-ip-port-map { config true; list ip-port-mapping { key router-id; leaf router-id { type uint32; } list intext-ip-protocol-type { key protocol; leaf protocol { type protocol-types; } list ip-port-map { key ip-port-internal; description "internal to external ip-port mapping"; leaf ip-port-internal { type string; } container ip-port-external { uses ip-port-entity; } } } } } */ public static IpPortExternal getExternalIpPortMap(DataBroker broker, Long routerId, String internalIpAddress, String internalPort, NAPTEntryEvent.Protocol protocol) { ProtocolTypes protocolType = NatUtil.getProtocolType(protocol); InstanceIdentifier ipPortMapId = buildIpToPortMapIdentifier(routerId, internalIpAddress, internalPort, protocolType); Optional ipPortMapData = read(broker, LogicalDatastoreType.CONFIGURATION, ipPortMapId); if (ipPortMapData.isPresent()) { IpPortMap ipPortMapInstance = ipPortMapData.get(); return ipPortMapInstance.getIpPortExternal(); } return null; } private static InstanceIdentifier buildIpToPortMapIdentifier(Long routerId, String internalIpAddress, String internalPort, ProtocolTypes protocolType) { InstanceIdentifier ipPortMapId = InstanceIdentifier.builder(IntextIpPortMap.class) .child(IpPortMapping.class, new IpPortMappingKey(routerId)) .child(IntextIpProtocolType.class, new IntextIpProtocolTypeKey(protocolType)) .child(IpPortMap.class, new IpPortMapKey(internalIpAddress + ":" + internalPort)).build(); return ipPortMapId; } static boolean isVpnInterfaceConfigured(DataBroker broker, String interfaceName) { InstanceIdentifier interfaceId = getVpnInterfaceIdentifier(interfaceName); return read(broker, LogicalDatastoreType.CONFIGURATION, interfaceId).isPresent(); } static InstanceIdentifier getVpnInterfaceIdentifier(String vpnInterfaceName) { return InstanceIdentifier.builder(VpnInterfaces.class) .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).build(); } static VpnInterface getConfiguredVpnInterface(DataBroker broker, String interfaceName) { InstanceIdentifier interfaceId = getVpnInterfaceIdentifier(interfaceName); return read(broker, LogicalDatastoreType.CONFIGURATION, interfaceId).orNull(); } public static String getDpnFromNodeConnectorId(NodeConnectorId portId) { /* * NodeConnectorId is of form 'openflow:dpnid:portnum' */ String[] split = portId.getValue().split(OF_URI_SEPARATOR); if (split == null || split.length != 3) { return null; } return split[1]; } public static BigInteger 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)); } /* container vpnMaps { list vpnMap { key vpn-id; leaf vpn-id { type yang:uuid; description "vpn-id"; } leaf name { type string; description "vpn name"; } leaf tenant-id { type yang:uuid; description "The UUID of the tenant that will own the subnet."; } leaf router-id { type yang:uuid; description "UUID of router "; } leaf-list network_ids { type yang:uuid; description "UUID representing the network "; } } } Method returns router Id associated to a VPN */ public static String getRouterIdfromVpnInstance(DataBroker broker, String vpnName) { InstanceIdentifier vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class) .child(VpnMap.class, new VpnMapKey(new Uuid(vpnName))).build(); Optional optionalVpnMap = read(broker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier); if (optionalVpnMap.isPresent()) { Uuid routerId = optionalVpnMap.get().getRouterId(); if (routerId != null) { return routerId.getValue(); } } return null; } static Uuid getVpnForRouter(DataBroker broker, String routerId) { InstanceIdentifier vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build(); Optional optionalVpnMaps = read(broker, LogicalDatastoreType.CONFIGURATION, vpnMapsIdentifier); if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) { List allMaps = optionalVpnMaps.get().getVpnMap(); if (routerId != null) { for (VpnMap vpnMap : allMaps) { if (vpnMap.getRouterId() != null && routerId.equals(vpnMap.getRouterId().getValue()) && !routerId.equals(vpnMap.getVpnId().getValue())) { return vpnMap.getVpnId(); } } } } return null; } static long getAssociatedVpn(DataBroker broker, String routerName) { InstanceIdentifier routerMappingId = NatUtil.getRouterVpnMappingId(routerName); Optional optRouterMapping = NatUtil.read(broker, LogicalDatastoreType.OPERATIONAL, routerMappingId); if (optRouterMapping.isPresent()) { Routermapping routerMapping = optRouterMapping.get(); return routerMapping.getVpnId(); } return NatConstants.INVALID_ID; } public static String getAssociatedVPN(DataBroker dataBroker, Uuid networkId, Logger log) { Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, networkId); if (vpnUuid == null) { log.error("No VPN instance associated with ext network {}", networkId); return null; } return vpnUuid.getValue(); } // TODO Clean up the exception handling @SuppressWarnings("checkstyle:IllegalCatch") public static void addPrefixToBGP(DataBroker broker, IBgpManager bgpManager, IFibManager fibManager, String rd, String prefix, String nextHopIp, long label, Logger log, RouteOrigin origin) { try { LOG.info("ADD: Adding Fib entry rd {} prefix {} nextHop {} label {}", rd, prefix, nextHopIp, label); if (nextHopIp == null) { log.error("addPrefix failed since nextHopIp cannot be null."); return; } fibManager.addOrUpdateFibEntry(broker, rd, null /*macAddress*/, prefix, Collections.singletonList(nextHopIp), VrfEntry.EncapType.Mplsgre, (int)label, 0 /*l3vni*/, null /*gatewayMacAddress*/, origin, null /*writeTxn*/); bgpManager.advertisePrefix(rd, prefix, Collections.singletonList(nextHopIp), (int) label); LOG.info("ADD: Added Fib entry rd {} prefix {} nextHop {} label {}", rd, prefix, nextHopIp, label); } catch (Exception e) { log.error("Add prefix failed", e); } } static InstanceIdentifier buildPortToIpMapIdentifier(String routerId, String portName) { InstanceIdentifier ipPortMapId = InstanceIdentifier.builder(FloatingIpInfo.class) .child(RouterPorts.class, new RouterPortsKey(routerId)).child(Ports.class, new PortsKey(portName)).build(); return ipPortMapId; } static InstanceIdentifier buildRouterPortsIdentifier(String routerId) { InstanceIdentifier routerInstanceIndentifier = InstanceIdentifier.builder(FloatingIpInfo.class) .child(RouterPorts.class, new RouterPortsKey(routerId)).build(); return routerInstanceIndentifier; } /* container snatint-ip-port-map { list intip-port-map { key router-id; leaf router-id { type uint32; } list ip-port { key internal-ip; leaf internal-ip { type string; } list int-ip-proto-type { key protocol; leaf protocol { type protocol-types; } leaf-list ports { type uint16; } } } } } Method returns InternalIp port List */ public static List getInternalIpPortListInfo(DataBroker dataBroker, Long routerId, String internalIpAddress, ProtocolTypes protocolType) { Optional optionalIpProtoType = read(dataBroker, LogicalDatastoreType.CONFIGURATION, buildSnatIntIpPortIdentifier(routerId, internalIpAddress, protocolType)); if (optionalIpProtoType.isPresent()) { return optionalIpProtoType.get().getPorts(); } return null; } public static InstanceIdentifier buildSnatIntIpPortIdentifier(Long routerId, String internalIpAddress, ProtocolTypes protocolType) { InstanceIdentifier intIpProtocolTypeId = InstanceIdentifier.builder(SnatintIpPortMap.class) .child(IntipPortMap.class, new IntipPortMapKey(routerId)) .child(IpPort.class, new IpPortKey(internalIpAddress)) .child(IntIpProtoType.class, new IntIpProtoTypeKey(protocolType)).build(); return intIpProtocolTypeId; } public static ProtocolTypes getProtocolType(NAPTEntryEvent.Protocol protocol) { ProtocolTypes protocolType = ProtocolTypes.TCP.toString().equals(protocol.toString()) ? ProtocolTypes.TCP : ProtocolTypes.UDP; return protocolType; } public static InstanceIdentifier getNaptSwitchesIdentifier() { return InstanceIdentifier.create(NaptSwitches.class); } public static InstanceIdentifier buildNaptSwitchRouterIdentifier(String routerId) { return InstanceIdentifier.create(NaptSwitches.class) .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId)); } public static String getGroupIdKey(String routerName) { return "snatmiss." + routerName; } public static long createGroupId(String groupIdKey, IdManagerService idManager) { AllocateIdInput getIdInput = new AllocateIdInputBuilder() .setPoolName(NatConstants.SNAT_IDPOOL_NAME).setIdKey(groupIdKey) .build(); try { Future> result = idManager.allocateId(getIdInput); RpcResult rpcResult = result.get(); return rpcResult.getResult().getIdValue(); } catch (NullPointerException | InterruptedException | ExecutionException e) { LOG.trace("", e); } return 0; } // TODO Clean up the exception handling @SuppressWarnings("checkstyle:IllegalCatch") public static void removePrefixFromBGP(DataBroker broker, IBgpManager bgpManager, IFibManager fibManager, String rd, String prefix, Logger log) { try { LOG.info("REMOVE: Removing Fib entry rd {} prefix {}", rd, prefix); fibManager.removeFibEntry(broker, rd, prefix, null); bgpManager.withdrawPrefix(rd, prefix); LOG.info("REMOVE: Removed Fib entry rd {} prefix {}", rd, prefix); } catch (Exception e) { log.error("Delete prefix failed", e); } } public static IpPortMapping getIportMapping(DataBroker broker, long routerId) { return read(broker, LogicalDatastoreType.CONFIGURATION, getIportMappingIdentifier(routerId)).orNull(); } public static InstanceIdentifier getIportMappingIdentifier(long 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) .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; } public static List getExternalIpsForRouter(DataBroker dataBroker, Long routerId) { Optional ipMappingOptional = read(dataBroker, LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId)); List externalIps = new ArrayList<>(); if (ipMappingOptional.isPresent()) { List ipMaps = ipMappingOptional.get().getIpMap(); for (IpMap ipMap : ipMaps) { externalIps.add(ipMap.getExternalIp()); } //remove duplicates return new ArrayList<>(new HashSet<>(externalIps)); } return null; } public static List getExternalIpsFromRouter(DataBroker dataBroker, String routerName) { Routers routerData = NatUtil.getRoutersFromConfigDS(dataBroker, routerName); return (routerData != null) ? routerData.getExternalIps() : Collections.emptyList(); } public static HashMap getExternalIpsLabelForRouter(DataBroker dataBroker, Long routerId) { Optional ipMappingOptional = read(dataBroker, LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId)); HashMap externalIpsLabel = new HashMap<>(); if (ipMappingOptional.isPresent()) { List ipMaps = ipMappingOptional.get().getIpMap(); for (IpMap ipMap : ipMaps) { externalIpsLabel.put(ipMap.getExternalIp(), ipMap.getLabel()); } return externalIpsLabel; } return null; } /* container external-ips-counter { config false; list external-counters{ key segment-id; leaf segment-id { type uint32; } list external-ip-counter { key external-ip; leaf external-ip { type string; } leaf counter { type uint8; } } } } */ public static String getLeastLoadedExternalIp(DataBroker dataBroker, long 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); if (externalCountersData.isPresent()) { ExternalCounters externalCounter = externalCountersData.get(); List externalIpCounterList = externalCounter.getExternalIpCounter(); short countOfLstLoadExtIp = 32767; for (ExternalIpCounter externalIpCounter : externalIpCounterList) { String curExternalIp = externalIpCounter.getExternalIp(); short countOfCurExtIp = externalIpCounter.getCounter(); if (countOfCurExtIp < countOfLstLoadExtIp) { countOfLstLoadExtIp = countOfCurExtIp; leastLoadedExternalIp = curExternalIp; } } } return leastLoadedExternalIp; } public static String[] getSubnetIpAndPrefix(DataBroker dataBroker, Uuid subnetId) { String subnetIP = getSubnetIp(dataBroker, subnetId); if (subnetIP != null) { return getSubnetIpAndPrefix(subnetIP); } return null; } public static String[] getSubnetIpAndPrefix(String subnetString) { String[] subnetSplit = subnetString.split("/"); String subnetIp = subnetSplit[0]; String subnetPrefix = "0"; if (subnetSplit.length == 2) { subnetPrefix = subnetSplit[1]; } return new String[] {subnetIp, subnetPrefix}; } public static String getSubnetIp(DataBroker dataBroker, Uuid subnetId) { InstanceIdentifier subnetmapId = InstanceIdentifier .builder(Subnetmaps.class) .child(Subnetmap.class, new SubnetmapKey(subnetId)) .build(); Optional removedSubnet = read(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetmapId); if (removedSubnet.isPresent()) { Subnetmap subnetMapEntry = removedSubnet.get(); return subnetMapEntry.getSubnetIp(); } return null; } public static String[] getExternalIpAndPrefix(String leastLoadedExtIpAddr) { String[] leastLoadedExtIpAddrSplit = leastLoadedExtIpAddr.split("/"); String leastLoadedExtIp = leastLoadedExtIpAddrSplit[0]; String leastLoadedExtIpPrefix = String.valueOf(NatConstants.DEFAULT_PREFIX); if (leastLoadedExtIpAddrSplit.length == 2) { leastLoadedExtIpPrefix = leastLoadedExtIpAddrSplit[1]; } return new String[] {leastLoadedExtIp, leastLoadedExtIpPrefix}; } public static List getDpnsForRouter(DataBroker dataBroker, String routerUuid) { InstanceIdentifier id = InstanceIdentifier.builder(NeutronRouterDpns.class) .child(RouterDpnList.class, new RouterDpnListKey(routerUuid)).build(); Optional routerDpnListData = read(dataBroker, LogicalDatastoreType.OPERATIONAL, id); List dpns = new ArrayList<>(); if (routerDpnListData.isPresent()) { List dpnVpninterfacesList = routerDpnListData.get().getDpnVpninterfacesList(); for (DpnVpninterfacesList dpnVpnInterface : dpnVpninterfacesList) { dpns.add(dpnVpnInterface.getDpnId()); } return dpns; } return null; } public static long getBgpVpnId(DataBroker dataBroker, String routerName) { long bgpVpnId = NatConstants.INVALID_ID; Uuid bgpVpnUuid = NatUtil.getVpnForRouter(dataBroker, routerName); if (bgpVpnUuid != null) { bgpVpnId = NatUtil.getVpnId(dataBroker, bgpVpnUuid.getValue()); } return bgpVpnId; } static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces .RouterInterface getConfiguredRouterInterface(DataBroker broker, String interfaceName) { Optional optRouterInterface = read(broker, LogicalDatastoreType.CONFIGURATION, NatUtil.getRouterInterfaceId(interfaceName)); if (optRouterInterface.isPresent()) { return optRouterInterface.get(); } return null; } static InstanceIdentifier getRouterInterfaceId(String interfaceName) { return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight .netvirt.l3vpn.rev130911.RouterInterfaces.class) .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces .RouterInterface.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces .RouterInterfaceKey(interfaceName)).build(); } static void addToNeutronRouterDpnsMap(DataBroker broker, String routerName, String interfaceName, OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) { BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, interfaceName); if (dpId.equals(BigInteger.ZERO)) { LOG.warn("NAT Service : Could not retrieve dp id for interface {} to handle router {} association model", interfaceName, routerName); return; } LOG.debug("NAT Service : Adding the Router {} and DPN {} for the Interface {} in the " + "ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName); InstanceIdentifier dpnVpnInterfacesListIdentifier = getRouterDpnId(routerName, dpId); Optional optionalDpnVpninterfacesList = read(broker, LogicalDatastoreType .OPERATIONAL, dpnVpnInterfacesListIdentifier); org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces routerInterface = new RouterInterfacesBuilder().setKey(new RouterInterfacesKey(interfaceName)) .setInterface(interfaceName).build(); if (optionalDpnVpninterfacesList.isPresent()) { LOG.debug("NAT Service : RouterDpnList already present for the Router {} and DPN {} for the " + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName); writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL, 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, true); } else { LOG.debug("NAT Service : Building new RouterDpnList for the Router {} and DPN {} for the " + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName); RouterDpnListBuilder routerDpnListBuilder = new RouterDpnListBuilder(); routerDpnListBuilder.setRouterId(routerName); DpnVpninterfacesListBuilder dpnVpnList = new DpnVpninterfacesListBuilder().setDpnId(dpId); List routerInterfaces = new ArrayList<>(); routerInterfaces.add(routerInterface); dpnVpnList.setRouterInterfaces(routerInterfaces); routerDpnListBuilder.setDpnVpninterfacesList(Collections.singletonList(dpnVpnList.build())); writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL, getRouterId(routerName), routerDpnListBuilder.build(), true); } } static void addToDpnRoutersMap(DataBroker broker, String routerName, String interfaceName, OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) { BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, interfaceName); if (dpId.equals(BigInteger.ZERO)) { LOG.warn("NAT Service : Could not retrieve dp id for interface {} to handle router {} association model", interfaceName, routerName); return; } LOG.debug("NAT Service : Adding the DPN {} and router {} for the Interface {} in the ODL-L3VPN : " + "DPNRouters map", dpId, routerName, interfaceName); InstanceIdentifier dpnRoutersListIdentifier = getDpnRoutersId(dpId); Optional optionalDpnRoutersList = read(broker, LogicalDatastoreType.OPERATIONAL, dpnRoutersListIdentifier); if (optionalDpnRoutersList.isPresent()) { RoutersList routersList = new RoutersListBuilder().setKey(new RoutersListKey(routerName)) .setRouter(routerName).build(); List routersListFromDs = optionalDpnRoutersList.get().getRoutersList(); if (!routersListFromDs.contains(routersList)) { LOG.debug("NAT Service : Router {} not present for the DPN {}" + " in the ODL-L3VPN : DPNRouters map", routerName, dpId); writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL, dpnRoutersListIdentifier .child(RoutersList.class, new RoutersListKey(routerName)), routersList, true); } else { LOG.debug("NAT Service : Router {} already mapped to the DPN {} in the ODL-L3VPN : DPNRouters map", routerName, dpId); } } else { LOG.debug("NAT Service : Building new DPNRoutersList for the Router {} present in the DPN {} " + "ODL-L3VPN : DPNRouters map", routerName, dpId); DpnRoutersListBuilder dpnRoutersListBuilder = new DpnRoutersListBuilder(); dpnRoutersListBuilder.setDpnId(dpId); RoutersListBuilder routersListBuilder = new RoutersListBuilder(); routersListBuilder.setRouter(routerName); dpnRoutersListBuilder.setRoutersList(Collections.singletonList(routersListBuilder.build())); writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL, getDpnRoutersId(dpId), dpnRoutersListBuilder.build(), true); } } static void removeFromNeutronRouterDpnsMap(DataBroker broker, String routerName, String interfaceName, BigInteger dpId, WriteTransaction writeOperTxn) { if (dpId.equals(BigInteger.ZERO)) { LOG.warn("NAT Service : Could not retrieve dp id for interface {} to handle router {} dissociation model", interfaceName, routerName); return; } InstanceIdentifier routerDpnListIdentifier = getRouterDpnId(routerName, dpId); Optional optionalRouterDpnList = NatUtil.read(broker, LogicalDatastoreType .OPERATIONAL, routerDpnListIdentifier); if (optionalRouterDpnList.isPresent()) { List routerInterfaces = optionalRouterDpnList.get().getRouterInterfaces(); org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces routerInterface = new RouterInterfacesBuilder().setKey(new RouterInterfacesKey(interfaceName)) .setInterface(interfaceName).build(); if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) { if (routerInterfaces.isEmpty()) { writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier); } else { writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, 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(interfaceName))); } } } } static void removeFromNeutronRouterDpnsMap(DataBroker broker, String routerName, BigInteger dpId, WriteTransaction writeOperTxn) { if (dpId.equals(BigInteger.ZERO)) { LOG.warn("NAT Service : DPN ID is invalid for the router {} ", routerName); return; } InstanceIdentifier routerDpnListIdentifier = getRouterDpnId(routerName, dpId); Optional optionalRouterDpnList = NatUtil.read(broker, LogicalDatastoreType .OPERATIONAL, routerDpnListIdentifier); if (optionalRouterDpnList.isPresent()) { LOG.debug("NAT Service : Removing the dpn-vpninterfaces-list from the odl-l3vpn:neutron-router-dpns model " + "for the router {}", routerName); writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier); } else { LOG.debug("NAT Service : dpn-vpninterfaces-list does not exist in the odl-l3vpn:neutron-router-dpns model " + "for the router {}", routerName); } } static void removeFromNeutronRouterDpnsMap(DataBroker broker, String routerName, String vpnInterfaceName, OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) { BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, vpnInterfaceName); if (dpId.equals(BigInteger.ZERO)) { LOG.warn("NAT Service : Could not retrieve dp id for interface {} to handle router {} dissociation model", vpnInterfaceName, routerName); return; } InstanceIdentifier routerDpnListIdentifier = getRouterDpnId(routerName, dpId); Optional optionalRouterDpnList = read(broker, LogicalDatastoreType .OPERATIONAL, routerDpnListIdentifier); if (optionalRouterDpnList.isPresent()) { List routerInterfaces = optionalRouterDpnList.get().getRouterInterfaces(); org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn .list.dpn.vpninterfaces.list.RouterInterfaces routerInterface = new RouterInterfacesBuilder().setKey(new RouterInterfacesKey(vpnInterfaceName)) .setInterface(vpnInterfaceName).build(); if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) { if (routerInterfaces.isEmpty()) { if (writeOperTxn != null) { writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier); } else { MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier); } } else { if (writeOperTxn != null) { writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, 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))); } else { MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, 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))); } } } } } static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName, OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) { BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, vpnInterfaceName); if (dpId.equals(BigInteger.ZERO)) { LOG.warn("NAT Service : removeFromDpnRoutersMap() : Could not retrieve DPN ID for interface {} " + "to handle router {} dissociation model", vpnInterfaceName, routerName); return; } removeFromDpnRoutersMap(broker, routerName, vpnInterfaceName, dpId, ifaceMgrRpcService, writeOperTxn); } static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName, BigInteger curDpnId, OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) { /* 1) Get the DpnRoutersList for the DPN. 2) Get the RoutersList identifier for the DPN and router. 3) Get the VPN interfaces for the router (routerList) through which it is connected to the DPN. 4) If the removed VPN interface is the only interface through which the router is connected to the DPN, then remove RouterList. */ LOG.debug("NAT Service : removeFromDpnRoutersMap() : Removing the DPN {} and router {} for the Interface {}" + " in the ODL-L3VPN : DPNRouters map", curDpnId, routerName, vpnInterfaceName); //Get the dpn-routers-list instance for the current DPN. InstanceIdentifier dpnRoutersListIdentifier = getDpnRoutersId(curDpnId); Optional dpnRoutersListData = read(broker, LogicalDatastoreType.OPERATIONAL, dpnRoutersListIdentifier); if (dpnRoutersListData == null || !dpnRoutersListData.isPresent()) { LOG.debug("NAT Service : dpn-routers-list is not present for DPN {} in the ODL-L3VPN:dpn-routers model", curDpnId); return; } //Get the routers-list instance for the router on the current DPN only InstanceIdentifier routersListIdentifier = getRoutersList(curDpnId, routerName); Optional routersListData = read(broker, LogicalDatastoreType.OPERATIONAL, routersListIdentifier); if (routersListData == null || !routersListData.isPresent()) { LOG.debug("NAT Service : routers-list is not present for the DPN {} in the ODL-L3VPN:dpn-routers model", curDpnId); return; } LOG.debug("NAT Service : Get the interfaces for the router {} from the NeutronVPN - router-interfaces-map", routerName); InstanceIdentifier routerInterfacesId = getRoutersInterfacesIdentifier(routerName); Optional routerInterfacesData = read(broker, LogicalDatastoreType.CONFIGURATION, routerInterfacesId); if (routerInterfacesData == null || !routerInterfacesData.isPresent()) { LOG.debug("NAT Service : Unable to get the routers list for the DPN {}. Possibly all subnets removed" + " from router {} OR Router {} has been deleted. Hence DPN router model WILL be cleared ", curDpnId, routerName, routerName); writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routersListIdentifier); return; } //Get the VM interfaces for the router on the current DPN only. List vmInterfaces = routerInterfacesData.get().getInterfaces(); if (vmInterfaces == null) { LOG.debug("NAT Service : VM interfaces are not present for the router {} in the " + "NeutronVPN - router-interfaces-map", routerName); return; } // 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) { String vmInterfaceName = vmInterface.getInterfaceId(); BigInteger vmDpnId = getDpnForInterface(ifaceMgrRpcService, vmInterfaceName); if (vmDpnId.equals(BigInteger.ZERO) || !vmDpnId.equals(curDpnId)) { LOG.debug("NAT Service : DPN ID {} for the removed interface {} is not the same as that of " + "the DPN ID for the checked interface {} ", curDpnId, vpnInterfaceName, vmDpnId, vmInterfaceName); continue; } if (!vmInterfaceName.equalsIgnoreCase(vpnInterfaceName)) { LOG.debug("NAT Service : Router {} is present in the DPN {} through the other interface {} " + "Hence DPN router model WOULD NOT be cleared", routerName, curDpnId, vmInterfaceName); return; } } LOG.debug("NAT Service : Router {} is present in the DPN {} only through the interface {} " + "Hence DPN router model WILL be cleared. Possibly last VM for the router " + "deleted in the DPN", routerName, curDpnId); writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, 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) { 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; try { GetDpidFromInterfaceInput dpIdInput = new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build(); Future> dpIdOutput = interfaceManagerRpcService.getDpidFromInterface(dpIdInput); RpcResult dpIdResult = dpIdOutput.get(); if (dpIdResult.isSuccessful()) { nodeId = dpIdResult.getResult().getDpid(); } else { LOG.error("NAT Service : Could not retrieve DPN Id for interface {}", ifName); } } catch (NullPointerException | InterruptedException | ExecutionException e) { LOG.error("NAT Service : Exception when getting dpn for interface {}", ifName, e); } return nodeId; } public static List getEgressActionsForInterface(OdlInterfaceRpcService interfaceManager, String ifName, Long tunnelKey) { return getEgressActionsForInterface(interfaceManager, ifName, tunnelKey, 0); } public static List getEgressActionsForInterface(OdlInterfaceRpcService interfaceManager, String ifName, Long tunnelKey, int pos) { LOG.debug("NAT Service : getEgressActionsForInterface called for interface {}", ifName); GetEgressActionsForInterfaceInputBuilder egressActionsBuilder = new GetEgressActionsForInterfaceInputBuilder() .setIntfName(ifName); if (tunnelKey != null) { egressActionsBuilder.setTunnelKey(tunnelKey); } List listActionInfo = new ArrayList<>(); try { Future> result = interfaceManager .getEgressActionsForInterface(egressActionsBuilder.build()); RpcResult rpcResult = result.get(); if (!rpcResult.isSuccessful()) { LOG.warn("RPC Call to Get egress actions for interface {} returned with Errors {}", ifName, rpcResult.getErrors()); } else { List actions = rpcResult.getResult().getAction(); for (Action action : actions) { org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionClass = action.getAction(); if (actionClass instanceof OutputActionCase) { listActionInfo.add(new ActionOutput(pos++, ((OutputActionCase) actionClass).getOutputAction().getOutputNodeConnector())); } else if (actionClass instanceof PushVlanActionCase) { listActionInfo.add(new ActionPushVlan(pos++)); } else if (actionClass instanceof SetFieldCase) { if (((SetFieldCase) actionClass).getSetField().getVlanMatch() != null) { int vlanVid = ((SetFieldCase) actionClass).getSetField().getVlanMatch().getVlanId() .getVlanId().getValue(); listActionInfo.add(new ActionSetFieldVlanVid(pos++, vlanVid)); } } else if (actionClass instanceof NxActionResubmitRpcAddGroupCase) { Short tableId = ((NxActionResubmitRpcAddGroupCase) actionClass).getNxResubmit().getTable(); 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())); } } } } catch (InterruptedException | ExecutionException e) { LOG.warn("Exception when egress actions for interface {}", ifName, e); } return listActionInfo; } public static Port getNeutronPortForRouterGetewayIp(DataBroker broker, IpAddress targetIP) { return getNeutronPortForIp(broker, targetIP, NeutronConstants.DEVICE_OWNER_GATEWAY_INF); } public static List getNeutronPorts(DataBroker broker) { InstanceIdentifier portsIdentifier = InstanceIdentifier.create(Neutron.class) .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports.class); Optional portsOptional = read(broker, LogicalDatastoreType.CONFIGURATION, portsIdentifier); if (!portsOptional.isPresent() || portsOptional.get().getPort() == null) { LOG.trace("No neutron ports found"); return Collections.EMPTY_LIST; } return portsOptional.get().getPort(); } 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()) { if (Objects.equals(ip.getIpAddress(), targetIP)) { return port; } } } } return null; } public static Uuid getSubnetIdForFloatingIp(Port port, IpAddress targetIP) { if (port == null) { return null; } for (FixedIps ip : port.getFixedIps()) { if (Objects.equals(ip.getIpAddress(), targetIP)) { return ip.getSubnetId(); } } return null; } public static Subnetmap getSubnetMap(DataBroker broker, Uuid subnetId) { InstanceIdentifier subnetmapId = InstanceIdentifier.builder(Subnetmaps.class) .child(Subnetmap.class, new SubnetmapKey(subnetId)).build(); return read(broker, LogicalDatastoreType.CONFIGURATION, subnetmapId).orNull(); } public static List getSubnetIdsFromNetworkId(DataBroker broker, Uuid networkId) { InstanceIdentifier id = InstanceIdentifier.builder(NetworkMaps.class) .child(NetworkMap.class, new NetworkMapKey(networkId)).build(); Optional optionalNetworkMap = read(broker, LogicalDatastoreType.CONFIGURATION, id); return optionalNetworkMap.isPresent() ? optionalNetworkMap.get().getSubnetIdList() : null; } public static String getSubnetGwMac(DataBroker broker, Uuid subnetId, String vpnName) { if (subnetId == null) { return null; } InstanceIdentifier subnetInst = InstanceIdentifier.create(Neutron.class).child(Subnets.class) .child(Subnet.class, new SubnetKey(subnetId)); Optional subnetOpt = read(broker, LogicalDatastoreType.CONFIGURATION, subnetInst); if (!subnetOpt.isPresent()) { return null; } IpAddress gatewayIp = subnetOpt.get().getGatewayIp(); if (gatewayIp == null) { LOG.trace("No GW ip found for subnet {}", subnetId.getValue()); return null; } InstanceIdentifier portIpInst = InstanceIdentifier.builder(NeutronVpnPortipPortData.class) .child(VpnPortipToPort.class, new VpnPortipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName)) .build(); Optional portIpToPortOpt = read(broker, LogicalDatastoreType.CONFIGURATION, portIpInst); if (portIpToPortOpt.isPresent()) { return portIpToPortOpt.get().getMacAddress(); } InstanceIdentifier learntIpInst = InstanceIdentifier.builder(LearntVpnVipToPortData.class) .child(LearntVpnVipToPort.class, new LearntVpnVipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName)) .build(); Optional learntIpToPortOpt = read(broker, LogicalDatastoreType.OPERATIONAL, learntIpInst); if (learntIpToPortOpt.isPresent()) { return learntIpToPortOpt.get().getMacAddress(); } LOG.error("No resolution was found to GW ip {} in subnet {}", gatewayIp, subnetId.getValue()); return null; } public static boolean isIPv6Subnet(String prefix) { return new IpPrefix(prefix.toCharArray()).getIpv6Prefix() != null; } static InstanceIdentifier getDpnRoutersId(BigInteger dpnId) { return InstanceIdentifier.builder(DpnRouters.class) .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId)).build(); } static InstanceIdentifier getRouterDpnId(String routerName, BigInteger dpnId) { return InstanceIdentifier.builder(NeutronRouterDpns.class) .child(RouterDpnList.class, new RouterDpnListKey(routerName)) .child(DpnVpninterfacesList.class, new DpnVpninterfacesListKey(dpnId)).build(); } static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces .Interface getInterface(DataBroker broker, String interfaceName) { Optional optInterface = read(broker, LogicalDatastoreType.CONFIGURATION, getInterfaceIdentifier(interfaceName)); if (optInterface.isPresent()) { return optInterface.get(); } return null; } static InstanceIdentifier getRouterId(String routerName) { return InstanceIdentifier.builder(NeutronRouterDpns.class) .child(RouterDpnList.class, new RouterDpnListKey(routerName)).build(); } protected static String getFloatingIpPortMacFromFloatingIpId(DataBroker broker, Uuid floatingIpId) { InstanceIdentifier id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId); Optional optFloatingIpIdToPortMapping = read(broker, LogicalDatastoreType .CONFIGURATION, id); if (optFloatingIpIdToPortMapping.isPresent()) { return optFloatingIpIdToPortMapping.get().getFloatingIpPortMacAddress(); } return null; } protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(DataBroker broker, Uuid floatingIpId) { InstanceIdentifier id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId); Optional optFloatingIpIdToPortMapping = read(broker, LogicalDatastoreType .CONFIGURATION, id); if (optFloatingIpIdToPortMapping.isPresent()) { return optFloatingIpIdToPortMapping.get().getFloatingIpPortSubnetId(); } return null; } static InstanceIdentifier buildfloatingIpIdToPortMappingIdentifier(Uuid floatingIpId) { return InstanceIdentifier.builder(FloatingIpPortInfo.class).child(FloatingIpIdToPortMapping.class, new FloatingIpIdToPortMappingKey(floatingIpId)).build(); } static InstanceIdentifier getInterfaceIdentifier(String interfaceName) { return InstanceIdentifier.builder(Interfaces.class) .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508 .interfaces.Interface.class, new InterfaceKey(interfaceName)).build(); } static final FutureCallback DEFAULT_CALLBACK = new FutureCallback() { @Override public void onSuccess(Void result) { LOG.debug("NAT Service : Success in Datastore operation"); } @Override public void onFailure(Throwable error) { LOG.error("NAT Service : Error in Datastore operation", error); } ; }; static void delete(DataBroker broker, LogicalDatastoreType datastoreType, InstanceIdentifier path) { delete(broker, datastoreType, path, DEFAULT_CALLBACK); } static void delete(DataBroker broker, LogicalDatastoreType datastoreType, InstanceIdentifier path, FutureCallback callback) { WriteTransaction tx = broker.newWriteOnlyTransaction(); tx.delete(datastoreType, path); Futures.addCallback(tx.submit(), callback); } static Interface getInterfaceStateFromOperDS(DataBroker dataBroker, String interfaceName) { InstanceIdentifier ifStateId = buildStateInterfaceId(interfaceName); Optional ifStateOptional = read(dataBroker, LogicalDatastoreType.OPERATIONAL, ifStateId); if (ifStateOptional.isPresent()) { return ifStateOptional.get(); } return null; } static InstanceIdentifier buildStateInterfaceId(String interfaceName) { InstanceIdentifier.InstanceIdentifierBuilder idBuilder = InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf .interfaces.rev140508.InterfacesState.class) .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; } public static Routers getRoutersFromConfigDS(DataBroker dataBroker, String routerName) { InstanceIdentifier routerIdentifier = NatUtil.buildRouterIdentifier(routerName); Optional routerData = NatUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, routerIdentifier); if (routerData.isPresent()) { return routerData.get(); } return null; } static void createRouterIdsConfigDS(DataBroker dataBroker, String routerName) { long routerId = NatUtil.getVpnId(dataBroker, routerName); if (routerId == NatConstants.INVALID_ID) { LOG.error("NAT Service : createRouterIdsConfigDS - invalid routerId for routerName {}", routerName); return; } RouterIds rtrs = new RouterIdsBuilder().setKey(new RouterIdsKey(routerId)) .setRouterId(routerId).setRouterName(routerName).build(); MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, buildRouterIdentifier(routerId), rtrs); } static String getExtGwMacAddFromRouterId(DataBroker broker, long routerId) { String routerName = getRouterName(broker, routerId); InstanceIdentifier id = buildRouterIdentifier(routerName); Optional routerData = read(broker, LogicalDatastoreType.CONFIGURATION, id); if (routerData.isPresent()) { return routerData.get().getExtGwMacAddress(); } return null; } }