X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=natservice%2Fnatservice-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fvpnservice%2Fnatservice%2Finternal%2FNaptFlowRemovedEventHandler.java;fp=natservice%2Fnatservice-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fvpnservice%2Fnatservice%2Finternal%2FNaptFlowRemovedEventHandler.java;h=f0206e2f7136030def0161bf83fa80a82d0675f6;hb=45320706157e8500aaa5e085d05ad4373c289d5f;hp=0000000000000000000000000000000000000000;hpb=5d9a52407447e8656f58ff5df8612dc59afe1508;p=vpnservice.git diff --git a/natservice/natservice-impl/src/main/java/org/opendaylight/vpnservice/natservice/internal/NaptFlowRemovedEventHandler.java b/natservice/natservice-impl/src/main/java/org/opendaylight/vpnservice/natservice/internal/NaptFlowRemovedEventHandler.java new file mode 100644 index 00000000..f0206e2f --- /dev/null +++ b/natservice/natservice-impl/src/main/java/org/opendaylight/vpnservice/natservice/internal/NaptFlowRemovedEventHandler.java @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2016 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.vpnservice.natservice.internal; + +import org.opendaylight.vpnservice.mdsalutil.MetaDataUtil; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowListener; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAdded; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemoved; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowUpdated; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeErrorNotification; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeExperimenterErrorNotification; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SwitchFlowRemoved; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.RemovedReasonFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.TcpMatchFields; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.UdpMatchFields; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer3Match; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer4Match; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatch; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatch; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.ip.port.map.IpPortExternal; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.opendaylight.vpnservice.mdsalutil.FlowEntity; +import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import java.math.BigInteger; + +public class NaptFlowRemovedEventHandler implements SalFlowListener{ + private DataBroker dataBroker; + private final EventDispatcher naptEventdispatcher; + private static final Logger LOG = LoggerFactory.getLogger(NaptFlowRemovedEventHandler.class); + private final NaptPacketInHandler naptPacketInHandler; + private IMdsalApiManager mdsalManager; + private NaptManager naptManager; + + public NaptFlowRemovedEventHandler(EventDispatcher eventDispatcher, DataBroker dataBroker, NaptPacketInHandler handler, + IMdsalApiManager mdsalManager, NaptManager naptManager) { + this.naptEventdispatcher = eventDispatcher; + this.dataBroker = dataBroker; + this.naptPacketInHandler = handler; + this.mdsalManager = mdsalManager; + this.naptManager = naptManager; + } + + @Override + public void onSwitchFlowRemoved(SwitchFlowRemoved switchFlowRemoved) { + +/* + If the removed flow is from the OUTBOUND NAPT table : + 1) Get the ActionInfo of the flow. + 2) From the ActionInfo of the flow get the internal IP address, port and the protocol. + 3) Get the Metadata matching info of the flow. + 4) From the Metadata matching info of the flow get router ID. + 5) Querry the container intext-ip-port-map using the router ID + and the internal IP address, port to get the external IP address, port + 6) Instantiate an NaptEntry event and populate the external IP address, port and the router ID. + 7) Place the NaptEntry event to the queue. +*/ + + short tableId = switchFlowRemoved.getTableId(); + RemovedReasonFlags removedReasonFlag = switchFlowRemoved.getRemovedReason(); + + if (tableId == NatConstants.OUTBOUND_NAPT_TABLE) { + LOG.info("NaptFlowRemovedEventHandler : onSwitchFlowRemoved() entry"); + + //Get the internal internal IP address and the port number from the IPv4 match. + Ipv4Prefix internalIpv4Address = null; + Layer3Match layer3Match = switchFlowRemoved.getMatch().getLayer3Match(); + if (layer3Match instanceof Ipv4Match) { + Ipv4Match internalIpv4Match = (Ipv4Match) layer3Match; + internalIpv4Address = internalIpv4Match.getIpv4Source(); + } + if(internalIpv4Address == null){ + LOG.error("NaptFlowRemovedEventHandler : Matching internal IP is null while retrieving the value from the Outbound NAPT flow"); + return; + } + //Get the internal IP as a string + String internalIpv4AddressAsString = internalIpv4Address.getValue(); + String[] internalIpv4AddressParts = internalIpv4AddressAsString.split("/"); + String internalIpv4HostAddress = null; + if(internalIpv4AddressParts.length >= 1){ + internalIpv4HostAddress = internalIpv4AddressParts[0]; + } + + //Get the protocol from the layer4 match + NAPTEntryEvent.Protocol protocol = null; + Integer internalPortNumber = null; + Layer4Match layer4Match = switchFlowRemoved.getMatch().getLayer4Match(); + if (layer4Match instanceof TcpMatch) { + TcpMatchFields tcpMatchFields = (TcpMatchFields)layer4Match; + internalPortNumber = tcpMatchFields.getTcpSourcePort().getValue(); + protocol = NAPTEntryEvent.Protocol.TCP; + }else if (layer4Match instanceof UdpMatch){ + UdpMatchFields udpMatchFields = (UdpMatchFields)layer4Match; + internalPortNumber = udpMatchFields.getUdpSourcePort().getValue(); + protocol = NAPTEntryEvent.Protocol.UDP; + } + if(protocol == null){ + LOG.error("NaptFlowRemovedEventHandler : Matching protocol is null while retrieving the value from the Outbound NAPT flow"); + return; + } + + //Get the router ID from the metadata. + Long routerId; + BigInteger metadata = switchFlowRemoved.getMatch().getMetadata().getMetadata(); + if(MetaDataUtil.getNatRouterIdFromMetadata(metadata) != 0) { + routerId = MetaDataUtil.getNatRouterIdFromMetadata(metadata); + }else { + LOG.error("NaptFlowRemovedEventHandler : Null exception while retrieving routerId"); + return; + } + + //Get the external IP address and the port from the model + IpPortExternal ipPortExternal = NatUtil.getExternalIpPortMap(dataBroker, routerId, internalIpv4HostAddress, internalPortNumber.toString(), protocol); + if(ipPortExternal == null){ + LOG.error("NaptFlowRemovedEventHandler : IpPortExternal is null while querried from the model"); + return; + } + String externalIpAddress = ipPortExternal.getIpAddress(); + int externalPortNumber = ipPortExternal.getPortNum(); + + //Create an NAPT event and place it in the queue. + NAPTEntryEvent naptEntryEvent = new NAPTEntryEvent(externalIpAddress, externalPortNumber, routerId, NAPTEntryEvent.Operation.DELETE, protocol); + naptEventdispatcher.addNaptEvent(naptEntryEvent); + + //Get the DPN ID from the Node + InstanceIdentifier nodeRef = switchFlowRemoved.getNode().getValue().firstIdentifierOf(Node.class); + String dpn = nodeRef.firstKeyOf(Node.class).getId().getValue(); + BigInteger dpnId = getDpnId(dpn); + + //Inform the MDSAL manager to inform about the flow removal. + String switchFlowRef = NatUtil.getNaptFlowRef(dpnId, tableId, String.valueOf(metadata), internalIpv4HostAddress, internalPortNumber); + LOG.debug("NaptFlowRemovedEventHandler : DPN ID {}, Metadata {}, SwitchFlowRef {}, internalIpv4HostAddress{}", dpnId, metadata, switchFlowRef, internalIpv4AddressAsString); + FlowEntity snatFlowEntity = NatUtil.buildFlowEntity(dpnId, tableId, switchFlowRef); + mdsalManager.removeFlow(snatFlowEntity); + + if(removedReasonFlag.isIDLETIMEOUT()) { + LOG.debug("Received flow removed notification due to idleTimeout of flow from switch for flowref {}",switchFlowRef); + //Remove the SourceIP:Port key from the Napt packet handler map. + String internalIpPortKey = internalIpv4HostAddress + ":" + internalPortNumber; + naptPacketInHandler.removeIncomingPacketMap(internalIpPortKey); + + //Remove the mapping of internal fixed ip/port to external ip/port from the datastore. + SessionAddress internalSessionAddress = new SessionAddress(internalIpv4HostAddress, internalPortNumber); + naptManager.releaseIpExtPortMapping(routerId, internalSessionAddress, protocol); + } else { + LOG.debug("Received flow removed notification due to flowdelete from switch for flowref {}",switchFlowRef); + } + + LOG.info("NaptFlowRemovedEventHandler : onSwitchFlowRemoved() exit"); + } + } + + private BigInteger getDpnId(String node) { + //openflow:1] + String temp[] = node.split(":"); + BigInteger dpnId = new BigInteger(temp[1]); + return dpnId; + + } + + @Override + public void onFlowAdded(FlowAdded arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void onFlowRemoved(FlowRemoved arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void onFlowUpdated(FlowUpdated arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void onNodeErrorNotification(NodeErrorNotification arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void onNodeExperimenterErrorNotification(NodeExperimenterErrorNotification arg0) { + // TODO Auto-generated method stub + + } + +}