use of org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.port.mod.port.Port in project netvirt by opendaylight.
the class NaptEventHandler method buildAndInstallNatFlowsOptionalRpc.
private Future<RpcResult<AddFlowOutput>> buildAndInstallNatFlowsOptionalRpc(BigInteger dpnId, short tableId, long vpnId, long routerId, long bgpVpnId, SessionAddress actualSourceAddress, SessionAddress translatedSourceAddress, NAPTEntryEvent.Protocol protocol, String extGwMacAddress, boolean sendRpc) {
LOG.debug("buildAndInstallNatFlowsOptionalRpc : Build and install table={} flow on dpnId {} and routerId {}", tableId, dpnId, routerId);
// Build the flow for replacing the actual IP and port with the translated IP and port.
int idleTimeout = 0;
if (tableId == NwConstants.OUTBOUND_NAPT_TABLE) {
idleTimeout = NatConstants.DEFAULT_NAPT_IDLE_TIMEOUT;
}
long intranetVpnId;
if (bgpVpnId != NatConstants.INVALID_ID) {
intranetVpnId = bgpVpnId;
} else {
intranetVpnId = routerId;
}
LOG.debug("buildAndInstallNatFlowsOptionalRpc : Intranet VPN ID {} Router ID {}", intranetVpnId, routerId);
String translatedIp = translatedSourceAddress.getIpAddress();
int translatedPort = translatedSourceAddress.getPortNumber();
String actualIp = actualSourceAddress.getIpAddress();
int actualPort = actualSourceAddress.getPortNumber();
String switchFlowRef = NatUtil.getNaptFlowRef(dpnId, tableId, String.valueOf(routerId), actualIp, actualPort);
FlowEntity snatFlowEntity = new FlowEntityBuilder().setDpnId(dpnId).setTableId(tableId).setFlowId(switchFlowRef).setPriority(NatConstants.DEFAULT_NAPT_FLOW_PRIORITY).setFlowName(NatConstants.NAPT_FLOW_NAME).setIdleTimeOut(idleTimeout).setHardTimeOut(0).setCookie(NatUtil.getCookieNaptFlow(routerId)).setMatchInfoList(buildAndGetMatchInfo(actualIp, actualPort, tableId, protocol, intranetVpnId)).setInstructionInfoList(buildAndGetSetActionInstructionInfo(translatedIp, translatedPort, intranetVpnId, vpnId, tableId, protocol, extGwMacAddress)).setSendFlowRemFlag(true).build();
// Install flows using RPC to prevent race with future packet-out that depends on this flow
Future<RpcResult<AddFlowOutput>> addFlowResult = null;
if (sendRpc) {
Flow flow = snatFlowEntity.getFlowBuilder().build();
NodeRef nodeRef = getNodeRef(dpnId);
FlowRef flowRef = getFlowRef(dpnId, flow);
AddFlowInput addFlowInput = new AddFlowInputBuilder(flow).setFlowRef(flowRef).setNode(nodeRef).build();
long startTime = System.currentTimeMillis();
addFlowResult = salFlowServiceRpc.addFlow(addFlowInput);
LOG.debug("buildAndInstallNatFlowsOptionalRpc : Time elapsed for salFlowServiceRpc table {}: {}ms ", tableId, System.currentTimeMillis() - startTime);
// Keep flow installation through MDSAL as well to be able to handle switch failures
startTime = System.currentTimeMillis();
mdsalManager.installFlow(snatFlowEntity);
LOG.trace("buildAndInstallNatFlowsOptionalRpc : Time Elapsed while installing table-{} " + "flow on DPN:{} for snat packet({},{}): {}ms", tableId, dpnId, actualSourceAddress.getIpAddress(), actualSourceAddress.getPortNumber(), System.currentTimeMillis() - startTime);
} else {
long startTime = System.currentTimeMillis();
mdsalManager.syncInstallFlow(snatFlowEntity);
LOG.trace("buildAndInstallNatFlowsOptionalRpc : Time Elapsed while installing table-{} " + "flow on DPN:{} for snat packet({},{}): {}ms", tableId, dpnId, actualSourceAddress.getIpAddress(), actualSourceAddress.getPortNumber(), System.currentTimeMillis() - startTime);
}
LOG.trace("buildAndInstallNatFlowsOptionalRpc : Exited");
return addFlowResult;
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.port.mod.port.Port in project netvirt by opendaylight.
the class NaptFlowRemovedEventHandler method onFlowRemoved.
@Override
public void onFlowRemoved(FlowRemoved flowRemoved) {
/*
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 = flowRemoved.getTableId();
RemovedFlowReason removedReasonFlag = flowRemoved.getReason();
if (tableId == NwConstants.OUTBOUND_NAPT_TABLE && RemovedFlowReason.OFPRRIDLETIMEOUT.equals(removedReasonFlag)) {
LOG.info("onFlowRemoved : triggered for table-{} entry", tableId);
// Get the internal internal IP address and the port number from the IPv4 match.
Ipv4Prefix internalIpv4Address = null;
Layer3Match layer3Match = flowRemoved.getMatch().getLayer3Match();
if (layer3Match instanceof Ipv4Match) {
Ipv4Match internalIpv4Match = (Ipv4Match) layer3Match;
internalIpv4Address = internalIpv4Match.getIpv4Source();
}
if (internalIpv4Address == null) {
LOG.error("onFlowRemoved : 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 = flowRemoved.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("onFlowRemoved : 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 = flowRemoved.getMatch().getMetadata().getMetadata();
if (MetaDataUtil.getNatRouterIdFromMetadata(metadata) != 0) {
routerId = MetaDataUtil.getNatRouterIdFromMetadata(metadata);
} else {
LOG.error("onFlowRemoved : Null exception while retrieving routerId");
return;
}
final String internalIpPortKey = routerId + NatConstants.COLON_SEPARATOR + internalIpv4HostAddress + NatConstants.COLON_SEPARATOR + internalPortNumber;
// 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("onFlowRemoved : IpPortExternal not found, BGP vpn might be " + "associated with router");
// router must be associated with BGP vpn ID
long bgpVpnId = routerId;
LOG.debug("onFlowRemoved : BGP VPN ID {}", bgpVpnId);
String vpnName = NatUtil.getRouterName(dataBroker, bgpVpnId);
String routerName = NatUtil.getRouterIdfromVpnInstance(dataBroker, vpnName);
if (routerName == null) {
LOG.error("onFlowRemoved : Unable to find router for VpnName {}", vpnName);
return;
}
routerId = NatUtil.getVpnId(dataBroker, routerName);
LOG.debug("onFlowRemoved : Router ID {}", routerId);
ipPortExternal = NatUtil.getExternalIpPortMap(dataBroker, routerId, internalIpv4HostAddress, internalPortNumber.toString(), protocol);
if (ipPortExternal == null) {
LOG.error("onFlowRemoved : IpPortExternal is null while queried from the " + "model for routerId {}", routerId);
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, null, false, null);
naptEventdispatcher.addFlowRemovedNaptEvent(naptEntryEvent);
// Get the DPN ID from the Node
InstanceIdentifier<Node> nodeRef = flowRemoved.getNode().getValue().firstIdentifierOf(Node.class);
String dpn = nodeRef.firstKeyOf(Node.class).getId().getValue();
BigInteger dpnId = getDpnId(dpn);
String switchFlowRef = NatUtil.getNaptFlowRef(dpnId, tableId, String.valueOf(routerId), internalIpv4HostAddress, internalPortNumber);
// Inform the MDSAL manager to inform about the flow removal.
LOG.debug("onFlowRemoved : DPN ID {}, Metadata {}, SwitchFlowRef {}, " + "internalIpv4HostAddress{}", dpnId, routerId, switchFlowRef, internalIpv4AddressAsString);
FlowEntity snatFlowEntity = NatUtil.buildFlowEntity(dpnId, tableId, switchFlowRef);
long startTime = System.currentTimeMillis();
mdsalManager.removeFlow(snatFlowEntity);
LOG.debug("onFlowRemoved : Elapsed time fo deleting table-{} flow for snat ({}) session:{}ms", tableId, internalIpPortKey, (System.currentTimeMillis() - startTime));
// Remove the SourceIP:Port key from the Napt packet handler map.
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);
LOG.info("onFlowRemoved : exit");
} else {
LOG.debug("onFlowRemoved : Received flow removed notification due to flowdelete from switch for flowref");
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.port.mod.port.Port in project netvirt by opendaylight.
the class NaptManager method removeNaptPortPool.
void removeNaptPortPool(String poolName) {
DeleteIdPoolInput deleteIdPoolInput = new DeleteIdPoolInputBuilder().setPoolName(poolName).build();
LOG.debug("removeNaptPortPool : Remove Napt port pool requested for : {}", poolName);
try {
Future<RpcResult<Void>> result = idManager.deleteIdPool(deleteIdPoolInput);
if (result != null && result.get().isSuccessful()) {
LOG.debug("removeNaptPortPool : Deleted PortPool {}", poolName);
} else {
LOG.error("removeNaptPortPool : Unable to delete PortPool {}", poolName);
}
} catch (InterruptedException | ExecutionException e) {
LOG.error("removeNaptPortPool : Failed to delete PortPool {} for NAPT Service", poolName, e);
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.port.mod.port.Port in project netvirt by opendaylight.
the class NaptManager method removeSnatIntIpPortDS.
// TODO Clean up the exception handling
@SuppressWarnings("checkstyle:IllegalCatch")
protected void removeSnatIntIpPortDS(long segmentId, SessionAddress address, NAPTEntryEvent.Protocol protocol) {
LOG.trace("removeSnatIntIpPortDS : method called for IntIpport {} of router {} ", address, segmentId);
ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
List<Integer> portList = NatUtil.getInternalIpPortListInfo(dataBroker, segmentId, address.getIpAddress(), protocolType);
if (portList.isEmpty() || !portList.contains(address.getPortNumber())) {
LOG.error("removeSnatIntIpPortDS : Internal IP {} for port {} entry not found in SnatIntIpPort DS", address.getIpAddress(), address.getPortNumber());
return;
}
LOG.trace("removeSnatIntIpPortDS : PortList {} retrieved for InternalIp {} of router {}", portList, address.getIpAddress(), segmentId);
Integer port = address.getPortNumber();
portList.remove(port);
IntIpProtoTypeBuilder builder = new IntIpProtoTypeBuilder();
IntIpProtoType intIpProtocolType = builder.setKey(new IntIpProtoTypeKey(protocolType)).setPorts(portList).build();
try {
MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, NatUtil.buildSnatIntIpPortIdentifier(segmentId, address.getIpAddress(), protocolType), intIpProtocolType);
} catch (Exception ex) {
LOG.error("removeSnatIntIpPortDS : Failed to write into snat-internal-ip-port-info with exception", ex);
}
LOG.debug("removeSnatIntIpPortDS : Removing SnatIp {} Port {} of router {} from SNATIntIpport datastore", address.getIpAddress(), address.getPortNumber(), segmentId);
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.port.mod.port.Port in project netvirt by opendaylight.
the class NaptManager method checkIpPortMap.
private SessionAddress checkIpPortMap(long segmentId, String internalIpPort, NAPTEntryEvent.Protocol protocol) {
LOG.debug("checkIpPortMap : called with segmentId {} and internalIpPort {}", segmentId, internalIpPort);
ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
// check if ip-port-map node is there
InstanceIdentifierBuilder<IpPortMap> idBuilder = InstanceIdentifier.builder(IntextIpPortMap.class).child(IpPortMapping.class, new IpPortMappingKey(segmentId)).child(IntextIpProtocolType.class, new IntextIpProtocolTypeKey(protocolType)).child(IpPortMap.class, new IpPortMapKey(internalIpPort));
InstanceIdentifier<IpPortMap> id = idBuilder.build();
Optional<IpPortMap> ipPortMapType = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
if (ipPortMapType.isPresent()) {
LOG.debug("checkIpPortMap : {}", ipPortMapType.get());
SessionAddress externalIpPort = new SessionAddress(ipPortMapType.get().getIpPortExternal().getIpAddress(), ipPortMapType.get().getIpPortExternal().getPortNum());
LOG.debug("checkIpPortMap : returning successfully externalIP {} and port {}", externalIpPort.getIpAddress(), externalIpPort.getPortNumber());
return externalIpPort;
}
// return null if not found
LOG.warn("checkIpPortMap : no-entry in checkIpPortMap, returning NULL [should be OK] for " + "segmentId {} and internalIPPort {}", segmentId, internalIpPort);
return null;
}
Aggregations