use of 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 in project netvirt by opendaylight.
the class NaptManager method getExternalAddressMapping.
/**
* method to get external ip/port mapping when provided with internal ip/port pair
* If already a mapping exist for the given input, then the existing mapping is returned
* instead of overwriting with new ip/port pair.
*
* @param segmentId - Router ID
* @param sourceAddress - internal ip address/port pair
* @param protocol - TCP/UDP
* @return external ip address/port
*/
// TODO Clean up the exception handling
@SuppressWarnings("checkstyle:IllegalCatch")
public SessionAddress getExternalAddressMapping(long segmentId, SessionAddress sourceAddress, NAPTEntryEvent.Protocol protocol) {
LOG.debug("getExternalAddressMapping : called with segmentId {}, internalIp {} and port {}", segmentId, sourceAddress.getIpAddress(), sourceAddress.getPortNumber());
/*
1. Get Internal IP, Port in IP:Port format
2. Inside DB with routerId get the list of entries and check if it matches with existing IP:Port
3. If True return SessionAddress of ExternalIp and Port
4. Else check ip Map and Form the ExternalIp and Port and update DB and then return ExternalIp and Port
*/
// SessionAddress externalIpPort = new SessionAddress();
String internalIpPort = sourceAddress.getIpAddress() + ":" + sourceAddress.getPortNumber();
// First check existing Port Map.
SessionAddress existingIpPort = checkIpPortMap(segmentId, internalIpPort, protocol);
if (existingIpPort != null) {
// populate externalIpPort from IpPortMap and return
LOG.debug("getExternalAddressMapping : successfully returning existingIpPort as {} and {}", existingIpPort.getIpAddress(), existingIpPort.getPortNumber());
return existingIpPort;
} else {
// Now check in ip-map
String externalIp = checkIpMap(segmentId, sourceAddress.getIpAddress());
if (externalIp == null) {
LOG.error("getExternalAddressMapping : Unexpected error, internal to external " + "ip map does not exist");
return null;
} else {
/* Logic assuming internalIp is always ip and not subnet
* case 1: externalIp is ip
* a) goto externalIp pool and getPort and return
* b) else return error
* case 2: externalIp is subnet
* a) Take first externalIp and goto that Pool and getPort
* if port -> return
* else Take second externalIp and create that Pool and getPort
* if port ->return
* else
* Continue same with third externalIp till we exhaust subnet
* b) Nothing worked return error
*/
SubnetUtils externalIpSubnet;
List<String> allIps = new ArrayList<>();
String subnetPrefix = "/" + String.valueOf(NatConstants.DEFAULT_PREFIX);
boolean extSubnetFlag = false;
if (!externalIp.contains(subnetPrefix)) {
extSubnetFlag = true;
externalIpSubnet = new SubnetUtils(externalIp);
allIps = Arrays.asList(externalIpSubnet.getInfo().getAllAddresses());
LOG.debug("getExternalAddressMapping : total count of externalIps available {}", externalIpSubnet.getInfo().getAddressCount());
} else {
LOG.debug("getExternalAddressMapping : getExternalAddress single ip case");
if (externalIp.contains(subnetPrefix)) {
// remove /32 what we got from checkIpMap
externalIp = externalIp.substring(0, externalIp.indexOf(subnetPrefix));
}
allIps.add(externalIp);
}
boolean nextExtIpFlag = false;
for (String extIp : allIps) {
LOG.info("getExternalAddressMapping : Looping externalIPs with externalIP now as {}", extIp);
if (nextExtIpFlag) {
createNaptPortPool(extIp);
LOG.debug("getExternalAddressMapping : Created Pool for next Ext IP {}", extIp);
}
AllocateIdInput getIdInput = new AllocateIdInputBuilder().setPoolName(extIp).setIdKey(internalIpPort).build();
try {
Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
RpcResult<AllocateIdOutput> rpcResult;
if (result != null && result.get().isSuccessful()) {
LOG.debug("getExternalAddressMapping : Got id from idManager");
rpcResult = result.get();
} else {
LOG.error("getExternalAddressMapping : getExternalAddressMapping, idManager could not " + "allocate id retry if subnet");
if (!extSubnetFlag) {
LOG.error("getExternalAddressMapping : getExternalAddressMapping returning null " + "for single IP case, may be ports exhausted");
return null;
}
LOG.debug("getExternalAddressMapping : Could be ports exhausted case, " + "try with another externalIP if possible");
nextExtIpFlag = true;
continue;
}
int extPort = rpcResult.getResult().getIdValue().intValue();
// Write to ip-port-map before returning
IpPortExternalBuilder ipExt = new IpPortExternalBuilder();
IpPortExternal ipPortExt = ipExt.setIpAddress(extIp).setPortNum(extPort).build();
IpPortMap ipm = new IpPortMapBuilder().setKey(new IpPortMapKey(internalIpPort)).setIpPortInternal(internalIpPort).setIpPortExternal(ipPortExt).build();
LOG.debug("getExternalAddressMapping : writing into ip-port-map with " + "externalIP {} and port {}", ipPortExt.getIpAddress(), ipPortExt.getPortNum());
try {
MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, getIpPortMapIdentifier(segmentId, internalIpPort, protocol), ipm);
} catch (UncheckedExecutionException uee) {
LOG.error("getExternalAddressMapping : Failed to write into ip-port-map with exception", uee);
}
// Write to snat-internal-ip-port-info
String internalIpAddress = sourceAddress.getIpAddress();
int ipPort = sourceAddress.getPortNumber();
ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
List<Integer> portList = new ArrayList<>(NatUtil.getInternalIpPortListInfo(dataBroker, segmentId, internalIpAddress, protocolType));
portList.add(ipPort);
IntIpProtoTypeBuilder builder = new IntIpProtoTypeBuilder();
IntIpProtoType intIpProtocolType = builder.setKey(new IntIpProtoTypeKey(protocolType)).setPorts(portList).build();
try {
MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, NatUtil.buildSnatIntIpPortIdentifier(segmentId, internalIpAddress, protocolType), intIpProtocolType);
} catch (Exception ex) {
LOG.error("getExternalAddressMapping : Failed to write into snat-internal-ip-port-info " + "with exception", ex);
}
SessionAddress externalIpPort = new SessionAddress(extIp, extPort);
LOG.debug("getExternalAddressMapping : successfully returning externalIP {} " + "and port {}", externalIpPort.getIpAddress(), externalIpPort.getPortNumber());
return externalIpPort;
} catch (InterruptedException | ExecutionException e) {
LOG.error("getExternalAddressMapping : Exception caught", e);
return null;
}
}
// end of for loop
}
// end of else ipmap present
}
// end of else check ipmap
LOG.error("getExternalAddressMapping : Unable to handle external IP address and port mapping with segmentId {}," + "internalIp {} and internalPort {}", segmentId, sourceAddress.getIpAddress(), sourceAddress.getPortNumber());
return null;
}
use of 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 in project netvirt by opendaylight.
the class NaptSwitchHA method removeSnatFlowsInOldNaptSwitch.
/* This method checks the switch that gone down is a NaptSwitch for a router.
If it is a NaptSwitch
1) selects new NAPT switch
2) installs nat flows in new NAPT switch
table 21(FIB)->26(PSNAT)->group(resubmit/napttunnel)->36(Terminating)->46(outbound)->47(resubmit)->21
3) modify the group and miss entry flow in other vSwitches pointing to newNaptSwitch
4) Remove nat flows in oldNaptSwitch
*/
/*public void handleNaptSwitchDown(BigInteger dpnId){
LOG.debug("handleNaptSwitchDown method is called with dpnId {}",dpnId);
BigInteger naptSwitch;
try {
NaptSwitches naptSwitches = NatUtil.getNaptSwitch(dataBroker);
if (naptSwitches == null || naptSwitches.getRouterToNaptSwitch() == null
|| naptSwitches.getRouterToNaptSwitch().isEmpty()) {
LOG.debug("NaptSwitchDown: NaptSwitch is not allocated for none of the routers");
return;
}
for (RouterToNaptSwitch routerToNaptSwitch : naptSwitches.getRouterToNaptSwitch()) {
String routerName = routerToNaptSwitch.getRouterName();
naptSwitch = routerToNaptSwitch.getPrimarySwitchId();
boolean naptStatus = isNaptSwitchDown(routerName,dpnId,naptSwitch);
if (!naptStatus) {
LOG.debug("NaptSwitchDown: Switch with DpnId {} is not naptSwitch for router {}",
dpnId, routerName);
} else {
removeSnatFlowsInOldNaptSwitch(routerName,naptSwitch);
return;
}
}
} catch (Exception ex) {
LOG.error("Exception in handleNaptSwitchDown method {}",ex);
}
}*/
protected void removeSnatFlowsInOldNaptSwitch(String routerName, Long routerId, BigInteger naptSwitch, Map<String, Long> externalIpmap, WriteTransaction removeFlowInvTx) {
// remove SNAT flows in old NAPT SWITCH
Uuid networkId = NatUtil.getNetworkIdFromRouterName(dataBroker, routerName);
String vpnName = getExtNetworkVpnName(routerName, networkId);
if (vpnName == null) {
LOG.error("removeSnatFlowsInOldNaptSwitch : Vpn is not associated to externalN/w of router {}", routerName);
return;
}
ProviderTypes extNwProvType = NatEvpnUtil.getExtNwProvTypeFromRouterName(dataBroker, routerName, networkId);
if (extNwProvType == null) {
LOG.error("removeSnatFlowsInOldNaptSwitch : Unable to retrieve the External Network Provider Type " + "for Router {}", routerName);
return;
}
if (extNwProvType == ProviderTypes.VXLAN) {
evpnNaptSwitchHA.evpnRemoveSnatFlowsInOldNaptSwitch(routerName, routerId, vpnName, naptSwitch, removeFlowInvTx);
} else {
// Remove the Terminating Service table entry which forwards the packet to Outbound NAPT Table
long tunnelId = NatUtil.getTunnelIdForNonNaptToNaptFlow(dataBroker, elanManager, idManager, routerId, routerName);
String tsFlowRef = externalRouterListener.getFlowRefTs(naptSwitch, NwConstants.INTERNAL_TUNNEL_TABLE, tunnelId);
FlowEntity tsNatFlowEntity = NatUtil.buildFlowEntity(naptSwitch, NwConstants.INTERNAL_TUNNEL_TABLE, tsFlowRef);
LOG.info("removeSnatFlowsInOldNaptSwitch : Remove the flow in table {} for the old napt switch " + "with the DPN ID {} and router ID {}", NwConstants.INTERNAL_TUNNEL_TABLE, naptSwitch, routerId);
mdsalManager.removeFlowToTx(tsNatFlowEntity, removeFlowInvTx);
}
if (NatUtil.isOpenStackVniSemanticsEnforcedForGreAndVxlan(elanManager, extNwProvType)) {
// Remove the flow table 25->44 If there is no FIP Match on table 25 (PDNAT_TABLE)
NatUtil.removePreDnatToSnatTableEntry(mdsalManager, naptSwitch, removeFlowInvTx);
}
// Remove the Outbound flow entry which forwards the packet to Outbound NAPT Table
String outboundNatFlowRef = externalRouterListener.getFlowRefOutbound(naptSwitch, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
FlowEntity outboundNatFlowEntity = NatUtil.buildFlowEntity(naptSwitch, NwConstants.OUTBOUND_NAPT_TABLE, outboundNatFlowRef);
LOG.info("Remove the flow in table {} for the old napt switch with the DPN ID {} and router ID {}", NwConstants.OUTBOUND_NAPT_TABLE, naptSwitch, routerId);
mdsalManager.removeFlowToTx(outboundNatFlowEntity, removeFlowInvTx);
// Remove the NAPT PFIB TABLE (47->21) which forwards the incoming packet to FIB Table matching on the
// External Subnet Vpn Id.
Collection<Uuid> externalSubnetIdsForRouter = NatUtil.getExternalSubnetIdsForRouter(dataBroker, routerName);
for (Uuid externalSubnetId : externalSubnetIdsForRouter) {
long subnetVpnId = NatUtil.getVpnId(dataBroker, externalSubnetId.getValue());
if (subnetVpnId != -1) {
String natPfibSubnetFlowRef = externalRouterListener.getFlowRefTs(naptSwitch, NwConstants.NAPT_PFIB_TABLE, subnetVpnId);
FlowEntity natPfibFlowEntity = NatUtil.buildFlowEntity(naptSwitch, NwConstants.NAPT_PFIB_TABLE, natPfibSubnetFlowRef);
mdsalManager.removeFlowToTx(natPfibFlowEntity, removeFlowInvTx);
LOG.debug("removeSnatFlowsInOldNaptSwitch : Removed the flow in table {} with external subnet " + "Vpn Id {} as metadata on Napt Switch {}", NwConstants.NAPT_PFIB_TABLE, subnetVpnId, naptSwitch);
}
}
// Remove the NAPT_PFIB_TABLE(47) flow entry forwards the packet to Fib Table for inbound traffic
// matching on the router ID.
String naptPFibflowRef = externalRouterListener.getFlowRefTs(naptSwitch, NwConstants.NAPT_PFIB_TABLE, routerId);
FlowEntity naptPFibFlowEntity = NatUtil.buildFlowEntity(naptSwitch, NwConstants.NAPT_PFIB_TABLE, naptPFibflowRef);
LOG.info("removeSnatFlowsInOldNaptSwitch : Remove the flow in table {} for the old napt switch " + "with the DPN ID {} and router ID {}", NwConstants.NAPT_PFIB_TABLE, naptSwitch, routerId);
mdsalManager.removeFlowToTx(naptPFibFlowEntity, removeFlowInvTx);
// Remove the NAPT_PFIB_TABLE(47) flow entry forwards the packet to Fib Table for outbound traffic
// matching on the vpn ID.
boolean switchSharedByRouters = false;
Uuid extNetworkId = NatUtil.getNetworkIdFromRouterName(dataBroker, routerName);
if (extNetworkId != null) {
List<String> routerNamesAssociated = getRouterIdsForExtNetwork(extNetworkId);
for (String routerNameAssociated : routerNamesAssociated) {
if (!routerNameAssociated.equals(routerName)) {
Long routerIdAssociated = NatUtil.getVpnId(dataBroker, routerNameAssociated);
BigInteger naptDpn = NatUtil.getPrimaryNaptfromRouterName(dataBroker, routerNameAssociated);
if (naptDpn != null && naptDpn.equals(naptSwitch)) {
LOG.debug("removeSnatFlowsInOldNaptSwitch : Napt switch {} is also acting as primary " + "for router {}", naptSwitch, routerIdAssociated);
switchSharedByRouters = true;
break;
}
}
}
if (!switchSharedByRouters) {
Long vpnId = getVpnIdForRouter(routerId, extNetworkId);
if (vpnId != NatConstants.INVALID_ID) {
String naptFibflowRef = externalRouterListener.getFlowRefTs(naptSwitch, NwConstants.NAPT_PFIB_TABLE, vpnId);
FlowEntity naptFibFlowEntity = NatUtil.buildFlowEntity(naptSwitch, NwConstants.NAPT_PFIB_TABLE, naptFibflowRef);
LOG.info("removeSnatFlowsInOldNaptSwitch : Remove the flow in table {} for the old napt switch" + " with the DPN ID {} and vpnId {}", NwConstants.NAPT_PFIB_TABLE, naptSwitch, vpnId);
mdsalManager.removeFlowToTx(naptFibFlowEntity, removeFlowInvTx);
} else {
LOG.error("removeSnatFlowsInOldNaptSwitch : Invalid vpnId retrieved for routerId {}", routerId);
return;
}
}
}
// Remove Fib entries,tables 20->44 ,36-> 44
String gwMacAddress = NatUtil.getExtGwMacAddFromRouterName(dataBroker, routerName);
if (externalIpmap != null && !externalIpmap.isEmpty()) {
for (Entry<String, Long> entry : externalIpmap.entrySet()) {
String externalIp = entry.getKey();
Long label = entry.getValue();
externalRouterListener.delFibTsAndReverseTraffic(naptSwitch, routerId, externalIp, vpnName, extNetworkId, label, gwMacAddress, true, removeFlowInvTx);
LOG.debug("removeSnatFlowsInOldNaptSwitch : Successfully removed fib entries in old naptswitch {} " + "for router {} and externalIps {} label {}", naptSwitch, routerId, externalIp, label);
}
} else {
List<String> externalIps = NatUtil.getExternalIpsForRouter(dataBroker, routerName);
if (networkId != null) {
externalRouterListener.clearFibTsAndReverseTraffic(naptSwitch, routerId, networkId, externalIps, null, gwMacAddress, removeFlowInvTx);
LOG.debug("removeSnatFlowsInOldNaptSwitch : Successfully removed fib entries in old naptswitch {} for " + "router {} with networkId {} and externalIps {}", naptSwitch, routerId, networkId, externalIps);
} else {
LOG.debug("removeSnatFlowsInOldNaptSwitch : External network not associated to router {}", routerId);
}
externalRouterListener.removeNaptFibExternalOutputFlows(routerId, naptSwitch, extNetworkId, externalIps, removeFlowInvTx);
}
// For the router ID get the internal IP , internal port and the corresponding external IP and external Port.
IpPortMapping ipPortMapping = NatUtil.getIportMapping(dataBroker, routerId);
if (ipPortMapping == null || ipPortMapping.getIntextIpProtocolType() == null || ipPortMapping.getIntextIpProtocolType().isEmpty()) {
LOG.warn("removeSnatFlowsInOldNaptSwitch : No Internal Ip Port mapping associated to router {}, " + "no flows need to be removed in oldNaptSwitch {}", routerId, naptSwitch);
return;
}
BigInteger cookieSnatFlow = NatUtil.getCookieNaptFlow(routerId);
List<IntextIpProtocolType> intextIpProtocolTypes = ipPortMapping.getIntextIpProtocolType();
for (IntextIpProtocolType intextIpProtocolType : intextIpProtocolTypes) {
if (intextIpProtocolType.getIpPortMap() == null || intextIpProtocolType.getIpPortMap().isEmpty()) {
LOG.debug("removeSnatFlowsInOldNaptSwitch : No {} session associated to router {}," + "no flows need to be removed in oldNaptSwitch {}", intextIpProtocolType.getProtocol(), routerId, naptSwitch);
break;
}
List<IpPortMap> ipPortMaps = intextIpProtocolType.getIpPortMap();
for (IpPortMap ipPortMap : ipPortMaps) {
String ipPortInternal = ipPortMap.getIpPortInternal();
String[] ipPortParts = ipPortInternal.split(":");
if (ipPortParts.length != 2) {
LOG.error("removeSnatFlowsInOldNaptSwitch : Unable to retrieve the Internal IP and port");
continue;
}
String internalIp = ipPortParts[0];
String internalPort = ipPortParts[1];
// Build and remove flow in outbound NAPT table
String switchFlowRef = NatUtil.getNaptFlowRef(naptSwitch, NwConstants.OUTBOUND_NAPT_TABLE, String.valueOf(routerId), internalIp, Integer.parseInt(internalPort));
FlowEntity outboundNaptFlowEntity = NatUtil.buildFlowEntity(naptSwitch, NwConstants.OUTBOUND_NAPT_TABLE, cookieSnatFlow, switchFlowRef);
LOG.info("removeSnatFlowsInOldNaptSwitch : Remove the flow in table {} for old napt switch " + "with the DPN ID {} and router ID {}", NwConstants.OUTBOUND_NAPT_TABLE, naptSwitch, routerId);
mdsalManager.removeFlowToTx(outboundNaptFlowEntity, removeFlowInvTx);
IpPortExternal ipPortExternal = ipPortMap.getIpPortExternal();
if (ipPortExternal == null) {
LOG.debug("removeSnatFlowsInOldNaptSwitch : External Ipport mapping not found for internalIp {} " + "with port {} for router {}", internalIp, internalPort, routerId);
continue;
}
String externalIp = ipPortExternal.getIpAddress();
int externalPort = ipPortExternal.getPortNum();
// Build and remove flow in inbound NAPT table
switchFlowRef = NatUtil.getNaptFlowRef(naptSwitch, NwConstants.INBOUND_NAPT_TABLE, String.valueOf(routerId), externalIp, externalPort);
FlowEntity inboundNaptFlowEntity = NatUtil.buildFlowEntity(naptSwitch, NwConstants.INBOUND_NAPT_TABLE, cookieSnatFlow, switchFlowRef);
LOG.info("removeSnatFlowsInOldNaptSwitch : Remove the flow in table {} for old napt switch with the " + "DPN ID {} and router ID {}", NwConstants.INBOUND_NAPT_TABLE, naptSwitch, routerId);
mdsalManager.removeFlowToTx(inboundNaptFlowEntity, removeFlowInvTx);
}
}
}
use of 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 in project netvirt by opendaylight.
the class ExternalRoutersListener method removeNaptFlowsFromActiveSwitch.
public void removeNaptFlowsFromActiveSwitch(long routerId, String routerName, BigInteger dpnId, Uuid networkId, String vpnName, @Nonnull Collection<String> externalIps, Collection<Uuid> externalSubnetList, WriteTransaction removeFlowInvTx, ProviderTypes extNwProvType) {
LOG.debug("removeNaptFlowsFromActiveSwitch : Remove NAPT flows from Active switch");
BigInteger cookieSnatFlow = NatUtil.getCookieNaptFlow(routerId);
// Remove the PSNAT entry which forwards the packet to Outbound NAPT Table (For the
// traffic which comes from the VMs of the NAPT switches)
String preSnatFlowRef = getFlowRefSnat(dpnId, NwConstants.PSNAT_TABLE, routerName);
FlowEntity preSnatFlowEntity = NatUtil.buildFlowEntity(dpnId, NwConstants.PSNAT_TABLE, preSnatFlowRef);
LOG.info("removeNaptFlowsFromActiveSwitch : Remove the flow in the {} for the active switch with the DPN ID {} " + "and router ID {}", NwConstants.PSNAT_TABLE, dpnId, routerId);
mdsalManager.removeFlowToTx(preSnatFlowEntity, removeFlowInvTx);
// Remove the Terminating Service table entry which forwards the packet to Outbound NAPT Table (For the
// traffic which comes from the VMs of the non NAPT switches)
long tunnelId = NatUtil.getTunnelIdForNonNaptToNaptFlow(dataBroker, elanManager, idManager, routerId, routerName);
String tsFlowRef = getFlowRefTs(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, tunnelId);
FlowEntity tsNatFlowEntity = NatUtil.buildFlowEntity(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, tsFlowRef);
LOG.info("removeNaptFlowsFromActiveSwitch : Remove the flow in the {} for the active switch with the DPN ID {} " + "and router ID {}", NwConstants.INTERNAL_TUNNEL_TABLE, dpnId, routerId);
mdsalManager.removeFlowToTx(tsNatFlowEntity, removeFlowInvTx);
// Remove the flow table 25->44 from NAPT Switch
if (NatUtil.isOpenStackVniSemanticsEnforcedForGreAndVxlan(elanManager, extNwProvType)) {
NatUtil.removePreDnatToSnatTableEntry(mdsalManager, dpnId, removeFlowInvTx);
}
// Remove the Outbound flow entry which forwards the packet to FIB Table
String outboundNatFlowRef = getFlowRefOutbound(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
FlowEntity outboundNatFlowEntity = NatUtil.buildFlowEntity(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, outboundNatFlowRef);
LOG.info("removeNaptFlowsFromActiveSwitch : Remove the flow in the {} for the active switch with the DPN ID {}" + " and router ID {}", NwConstants.OUTBOUND_NAPT_TABLE, dpnId, routerId);
mdsalManager.removeFlowToTx(outboundNatFlowEntity, removeFlowInvTx);
removeNaptFibExternalOutputFlows(routerId, dpnId, networkId, externalIps, removeFlowInvTx);
// External Subnet Vpn Id.
for (Uuid externalSubnetId : externalSubnetList) {
long subnetVpnId = NatUtil.getVpnId(dataBroker, externalSubnetId.getValue());
if (subnetVpnId != -1) {
String natPfibSubnetFlowRef = getFlowRefTs(dpnId, NwConstants.NAPT_PFIB_TABLE, subnetVpnId);
FlowEntity natPfibFlowEntity = NatUtil.buildFlowEntity(dpnId, NwConstants.NAPT_PFIB_TABLE, natPfibSubnetFlowRef);
mdsalManager.removeFlowToTx(natPfibFlowEntity, removeFlowInvTx);
LOG.debug("removeNaptFlowsFromActiveSwitch : Removed the flow in table {} with external subnet " + "Vpn Id {} as metadata on Napt Switch {}", NwConstants.NAPT_PFIB_TABLE, subnetVpnId, dpnId);
}
}
// Remove the NAPT PFIB TABLE which forwards the incoming packet to FIB Table matching on the router ID.
String natPfibFlowRef = getFlowRefTs(dpnId, NwConstants.NAPT_PFIB_TABLE, routerId);
FlowEntity natPfibFlowEntity = NatUtil.buildFlowEntity(dpnId, NwConstants.NAPT_PFIB_TABLE, natPfibFlowRef);
LOG.info("removeNaptFlowsFromActiveSwitch : Remove the flow in the {} for the active switch with the DPN ID {} " + "and router ID {}", NwConstants.NAPT_PFIB_TABLE, dpnId, routerId);
mdsalManager.removeFlowToTx(natPfibFlowEntity, removeFlowInvTx);
// Long vpnId = NatUtil.getVpnId(dataBroker, routerId);
// - This does not work since ext-routers is deleted already - no network info
// Get the VPN ID from the ExternalNetworks model
long vpnId = -1;
if (vpnName == null || vpnName.isEmpty()) {
// ie called from router delete cases
Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, networkId);
LOG.debug("removeNaptFlowsFromActiveSwitch : vpnUuid is {}", vpnUuid);
if (vpnUuid != null) {
vpnId = NatUtil.getVpnId(dataBroker, vpnUuid.getValue());
LOG.debug("removeNaptFlowsFromActiveSwitch : vpnId {} for external network {} router delete or " + "disableSNAT scenario", vpnId, networkId);
}
} else {
// ie called from disassociate vpn case
LOG.debug("removeNaptFlowsFromActiveSwitch : This is disassociate nw with vpn case with vpnName {}", vpnName);
vpnId = NatUtil.getVpnId(dataBroker, vpnName);
LOG.debug("removeNaptFlowsFromActiveSwitch : vpnId for disassociate nw with vpn scenario {}", vpnId);
}
if (vpnId != NatConstants.INVALID_ID) {
// Remove the NAPT PFIB TABLE which forwards the outgoing packet to FIB Table matching on the VPN ID.
String natPfibVpnFlowRef = getFlowRefTs(dpnId, NwConstants.NAPT_PFIB_TABLE, vpnId);
FlowEntity natPfibVpnFlowEntity = NatUtil.buildFlowEntity(dpnId, NwConstants.NAPT_PFIB_TABLE, natPfibVpnFlowRef);
LOG.info("removeNaptFlowsFromActiveSwitch : Remove the flow in {} for the active switch with the DPN ID {} " + "and VPN ID {}", NwConstants.NAPT_PFIB_TABLE, dpnId, vpnId);
mdsalManager.removeFlowToTx(natPfibVpnFlowEntity, removeFlowInvTx);
}
// For the router ID get the internal IP , internal port and the corresponding external IP and external Port.
IpPortMapping ipPortMapping = NatUtil.getIportMapping(dataBroker, routerId);
if (ipPortMapping == null) {
LOG.error("removeNaptFlowsFromActiveSwitch : Unable to retrieve the IpPortMapping");
return;
}
List<IntextIpProtocolType> intextIpProtocolTypes = ipPortMapping.getIntextIpProtocolType();
for (IntextIpProtocolType intextIpProtocolType : intextIpProtocolTypes) {
List<IpPortMap> ipPortMaps = intextIpProtocolType.getIpPortMap();
for (IpPortMap ipPortMap : ipPortMaps) {
String ipPortInternal = ipPortMap.getIpPortInternal();
String[] ipPortParts = ipPortInternal.split(":");
if (ipPortParts.length != 2) {
LOG.error("removeNaptFlowsFromActiveSwitch : Unable to retrieve the Internal IP and port");
return;
}
String internalIp = ipPortParts[0];
String internalPort = ipPortParts[1];
// Build the flow for the outbound NAPT table
naptPacketInHandler.removeIncomingPacketMap(routerId + NatConstants.COLON_SEPARATOR + internalIp + NatConstants.COLON_SEPARATOR + internalPort);
String switchFlowRef = NatUtil.getNaptFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, String.valueOf(routerId), internalIp, Integer.parseInt(internalPort));
FlowEntity outboundNaptFlowEntity = NatUtil.buildFlowEntity(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, cookieSnatFlow, switchFlowRef);
LOG.info("removeNaptFlowsFromActiveSwitch : Remove the flow in the {} for the active switch " + "with the DPN ID {} and router ID {}", NwConstants.OUTBOUND_NAPT_TABLE, dpnId, routerId);
mdsalManager.removeFlowToTx(outboundNaptFlowEntity, removeFlowInvTx);
IpPortExternal ipPortExternal = ipPortMap.getIpPortExternal();
String externalIp = ipPortExternal.getIpAddress();
int externalPort = ipPortExternal.getPortNum();
// Build the flow for the inbound NAPT table
switchFlowRef = NatUtil.getNaptFlowRef(dpnId, NwConstants.INBOUND_NAPT_TABLE, String.valueOf(routerId), externalIp, externalPort);
FlowEntity inboundNaptFlowEntity = NatUtil.buildFlowEntity(dpnId, NwConstants.INBOUND_NAPT_TABLE, cookieSnatFlow, switchFlowRef);
LOG.info("removeNaptFlowsFromActiveSwitch : Remove the flow in the {} for the active active switch " + "with the DPN ID {} and router ID {}", NwConstants.INBOUND_NAPT_TABLE, dpnId, routerId);
mdsalManager.removeFlowToTx(inboundNaptFlowEntity, removeFlowInvTx);
}
}
}
use of 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 in project netvirt by opendaylight.
the class NaptSwitchHA method handleNatFlowsInNewNaptSwitch.
// TODO Clean up the exception handling
@SuppressWarnings("checkstyle:IllegalCatch")
private boolean handleNatFlowsInNewNaptSwitch(String routerName, Long routerId, BigInteger oldNaptSwitch, BigInteger newNaptSwitch, Long routerVpnId, Uuid networkId) {
LOG.debug("handleNatFlowsInNewNaptSwitch : Proceeding to install flows in newNaptSwitch {} for routerId {}", newNaptSwitch, routerId);
IpPortMapping ipPortMapping = NatUtil.getIportMapping(dataBroker, routerId);
if (ipPortMapping == null || ipPortMapping.getIntextIpProtocolType() == null || ipPortMapping.getIntextIpProtocolType().isEmpty()) {
LOG.debug("handleNatFlowsInNewNaptSwitch : No Internal Ip Port mapping associated to router {}," + "no flows need to be installed in newNaptSwitch {}", routerId, newNaptSwitch);
return true;
}
// getvpnId
Long vpnId = getVpnIdForRouter(routerId, networkId);
if (vpnId == NatConstants.INVALID_ID) {
LOG.error("handleNatFlowsInNewNaptSwitch : Invalid vpnId for routerId {}", routerId);
return false;
}
Long bgpVpnId;
if (routerId.equals(routerVpnId)) {
bgpVpnId = NatConstants.INVALID_ID;
} else {
bgpVpnId = routerVpnId;
}
LOG.debug("handleNatFlowsInNewNaptSwitch : retrieved bgpVpnId {} for router {}", bgpVpnId, routerId);
// Get the External Gateway MAC Address
String extGwMacAddress = NatUtil.getExtGwMacAddFromRouterName(dataBroker, routerName);
if (extGwMacAddress != null) {
LOG.debug("handleNatFlowsInNewNaptSwitch :External Gateway MAC address {} found for External Router ID {}", extGwMacAddress, routerId);
} else {
LOG.error("handleNatFlowsInNewNaptSwitch : No External Gateway MAC address found for External Router ID {}", routerId);
return false;
}
for (IntextIpProtocolType protocolType : ipPortMapping.getIntextIpProtocolType()) {
if (protocolType.getIpPortMap() == null || protocolType.getIpPortMap().isEmpty()) {
LOG.debug("handleNatFlowsInNewNaptSwitch : No {} session associated to router {}", protocolType.getProtocol(), routerId);
return true;
}
for (IpPortMap intIpPortMap : protocolType.getIpPortMap()) {
String internalIpAddress = intIpPortMap.getIpPortInternal().split(":")[0];
String intportnum = intIpPortMap.getIpPortInternal().split(":")[1];
LOG.debug("handleNatFlowsInNewNaptSwitch : Found Internal IP Address {} and Port Number {}", internalIpAddress, intportnum);
// Get the external IP address and the port from the model
NAPTEntryEvent.Protocol proto = protocolType.getProtocol().toString().equals(ProtocolTypes.TCP.toString()) ? NAPTEntryEvent.Protocol.TCP : NAPTEntryEvent.Protocol.UDP;
IpPortExternal ipPortExternal = NatUtil.getExternalIpPortMap(dataBroker, routerId, internalIpAddress, intportnum, proto);
if (ipPortExternal == null) {
LOG.debug("handleNatFlowsInNewNaptSwitch : External Ipport mapping is not found for internalIp {} " + "with port {}", internalIpAddress, intportnum);
continue;
}
String externalIpAddress = ipPortExternal.getIpAddress();
Integer extportNumber = ipPortExternal.getPortNum();
LOG.debug("handleNatFlowsInNewNaptSwitch : ExternalIPport {}:{} mapping for internal ipport {}:{}", externalIpAddress, extportNumber, internalIpAddress, intportnum);
SessionAddress sourceAddress = new SessionAddress(internalIpAddress, Integer.parseInt(intportnum));
SessionAddress externalAddress = new SessionAddress(externalIpAddress, extportNumber);
// checking naptSwitch status before installing flows
if (getSwitchStatus(newNaptSwitch)) {
// Install the flow in newNaptSwitch Inbound NAPT table.
try {
naptEventHandler.buildAndInstallNatFlows(newNaptSwitch, NwConstants.INBOUND_NAPT_TABLE, vpnId, routerId, bgpVpnId, externalAddress, sourceAddress, proto, extGwMacAddress);
} catch (RuntimeException ex) {
LOG.error("handleNatFlowsInNewNaptSwitch : Failed to add flow in INBOUND_NAPT_TABLE for " + "routerid {} dpnId {} extIpport{}:{} proto {} ipport {}:{} BgpVpnId {}", routerId, newNaptSwitch, externalAddress, extportNumber, proto, internalIpAddress, intportnum, bgpVpnId);
return false;
}
LOG.debug("handleNatFlowsInNewNaptSwitch : Successfully installed a flow in Primary switch {} " + "Inbound NAPT table for router {} ipport {}:{} proto {} extIpport {}:{} BgpVpnId {}", newNaptSwitch, routerId, internalIpAddress, intportnum, proto, externalAddress, extportNumber, bgpVpnId);
// Install the flow in newNaptSwitch Outbound NAPT table.
try {
naptEventHandler.buildAndInstallNatFlows(newNaptSwitch, NwConstants.OUTBOUND_NAPT_TABLE, vpnId, routerId, bgpVpnId, sourceAddress, externalAddress, proto, extGwMacAddress);
} catch (RuntimeException ex) {
LOG.error("handleNatFlowsInNewNaptSwitch : Failed to add flow in OUTBOUND_NAPT_TABLE for " + "routerid {} dpnId {} ipport {}:{} proto {} extIpport {}:{} BgpVpnId {}", routerId, newNaptSwitch, internalIpAddress, intportnum, proto, externalAddress, extportNumber, bgpVpnId, ex);
return false;
}
LOG.debug("handleNatFlowsInNewNaptSwitch : Successfully installed a flow in Primary switch {} " + "Outbound NAPT table for router {} ipport {}:{} proto {} extIpport {}:{} BgpVpnId {}", newNaptSwitch, routerId, internalIpAddress, intportnum, proto, externalAddress, extportNumber, bgpVpnId);
} else {
LOG.error("handleNatFlowsInNewNaptSwitch : NewNaptSwitch {} gone down while installing flows " + "from oldNaptswitch {}", newNaptSwitch, oldNaptSwitch);
return false;
}
}
}
return true;
}
Aggregations