use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.sr.rev130819.SegmentId 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.params.xml.ns.yang.topology.sr.rev130819.SegmentId in project netvirt by opendaylight.
the class NaptManager method checkIpMap.
protected String checkIpMap(long segmentId, String internalIp) {
LOG.debug("checkIpMap : called with segmentId {} and internalIp {}", segmentId, internalIp);
String externalIp;
// check if ip-map node is there
InstanceIdentifierBuilder<IpMapping> idBuilder = InstanceIdentifier.builder(IntextIpMap.class).child(IpMapping.class, new IpMappingKey(segmentId));
InstanceIdentifier<IpMapping> id = idBuilder.build();
Optional<IpMapping> ipMapping = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
if (ipMapping.isPresent()) {
List<IpMap> ipMaps = ipMapping.get().getIpMap();
for (IpMap ipMap : ipMaps) {
if (ipMap.getInternalIp().equals(internalIp)) {
LOG.debug("checkIpMap : IpMap : {}", ipMap);
externalIp = ipMap.getExternalIp();
LOG.debug("checkIpMap : successfully returning externalIp {}", externalIp);
return externalIp;
} else if (ipMap.getInternalIp().contains("/")) {
// subnet case
SubnetUtils subnetUtils = new SubnetUtils(ipMap.getInternalIp());
SubnetInfo subnetInfo = subnetUtils.getInfo();
if (subnetInfo.isInRange(internalIp)) {
LOG.debug("checkIpMap : internalIp {} found to be IpMap of internalIpSubnet {}", internalIp, ipMap.getInternalIp());
externalIp = ipMap.getExternalIp();
LOG.debug("checkIpMap : checkIpMap successfully returning externalIp {}", externalIp);
return externalIp;
}
}
}
}
// return null if not found
LOG.error("checkIpMap : failed, returning NULL for segmentId {} and internalIp {}", segmentId, internalIp);
return null;
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.sr.rev130819.SegmentId in project netvirt by opendaylight.
the class ExternalRoutersListener method subnetRegisterMapping.
protected void subnetRegisterMapping(Routers routerEntry, Uint32 segmentId) {
LOG.debug("subnetRegisterMapping : Fetching values from extRouters model");
List<String> externalIps = NatUtil.getIpsListFromExternalIps(new ArrayList<ExternalIps>(routerEntry.nonnullExternalIps().values()));
int counter = 0;
int extIpCounter = externalIps.size();
LOG.debug("subnetRegisterMapping : counter values before looping counter {} and extIpCounter {}", counter, extIpCounter);
@Nullable List<Uuid> subnetIds = routerEntry.getSubnetIds();
if (subnetIds == null) {
return;
}
for (Uuid subnet : subnetIds) {
LOG.debug("subnetRegisterMapping : Looping internal subnets for subnet {}", subnet);
InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class, new SubnetmapKey(subnet)).build();
Optional<Subnetmap> sn;
try {
sn = SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetmapId);
} catch (InterruptedException | ExecutionException e) {
LOG.error("Failed to read SubnetMap for subnetmap Id {}", subnetmapId, e);
sn = Optional.empty();
}
if (sn.isPresent()) {
// subnets
Subnetmap subnetmapEntry = sn.get();
String subnetString = subnetmapEntry.getSubnetIp();
String[] subnetSplit = subnetString.split("/");
String subnetIp = subnetSplit[0];
try {
InetAddress address = InetAddress.getByName(subnetIp);
if (address instanceof Inet6Address) {
LOG.debug("subnetRegisterMapping : Skipping ipv6 subnet {} for the router {} with ipv6 address " + "{} ", subnet, routerEntry.getRouterName(), address);
continue;
}
} catch (UnknownHostException e) {
LOG.error("subnetRegisterMapping : Invalid ip address {}", subnetIp, e);
return;
}
String subnetPrefix = "0";
if (subnetSplit.length == 2) {
subnetPrefix = subnetSplit[1];
}
IPAddress subnetAddr = new IPAddress(subnetIp, Integer.parseInt(subnetPrefix));
LOG.debug("subnetRegisterMapping : subnetAddr is {} and subnetPrefix is {}", subnetAddr.getIpAddress(), subnetAddr.getPrefixLength());
// externalIps
LOG.debug("subnetRegisterMapping : counter values counter {} and extIpCounter {}", counter, extIpCounter);
if (extIpCounter != 0) {
if (counter < extIpCounter) {
String[] ipSplit = externalIps.get(counter).split("/");
String externalIp = ipSplit[0];
String extPrefix = Short.toString(NatConstants.DEFAULT_PREFIX);
if (ipSplit.length == 2) {
extPrefix = ipSplit[1];
}
IPAddress externalIpAddr = new IPAddress(externalIp, Integer.parseInt(extPrefix));
LOG.debug("subnetRegisterMapping : externalIp is {} and extPrefix is {}", externalIpAddr.getIpAddress(), externalIpAddr.getPrefixLength());
naptManager.registerMapping(segmentId, subnetAddr, externalIpAddr);
LOG.debug("subnetRegisterMapping : Called registerMapping for subnetIp {}, prefix {}, " + "externalIp {}. prefix {}", subnetIp, subnetPrefix, externalIp, extPrefix);
} else {
// Reset the counter which runs on externalIps for round-robbin effect
counter = 0;
LOG.debug("subnetRegisterMapping : Counter on externalIps got reset");
String[] ipSplit = externalIps.get(counter).split("/");
String externalIp = ipSplit[0];
String extPrefix = Short.toString(NatConstants.DEFAULT_PREFIX);
if (ipSplit.length == 2) {
extPrefix = ipSplit[1];
}
IPAddress externalIpAddr = new IPAddress(externalIp, Integer.parseInt(extPrefix));
LOG.debug("subnetRegisterMapping : externalIp is {} and extPrefix is {}", externalIpAddr.getIpAddress(), externalIpAddr.getPrefixLength());
naptManager.registerMapping(segmentId, subnetAddr, externalIpAddr);
LOG.debug("subnetRegisterMapping : Called registerMapping for subnetIp {}, prefix {}, " + "externalIp {}. prefix {}", subnetIp, subnetPrefix, externalIp, extPrefix);
}
}
counter++;
LOG.debug("subnetRegisterMapping : Counter on externalIps incremented to {}", counter);
} else {
LOG.warn("subnetRegisterMapping : No internal subnets present in extRouters Model");
}
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.sr.rev130819.SegmentId in project netvirt by opendaylight.
the class NaptEventHandler method buildAndGetSetActionInstructionInfo.
@NonNull
private static List<InstructionInfo> buildAndGetSetActionInstructionInfo(String ipAddress, int port, Uint32 segmentId, Uint32 vpnId, short tableId, NAPTEntryEvent.Protocol protocol, String extGwMacAddress) {
ActionInfo ipActionInfo = null;
ActionInfo macActionInfo = null;
ActionInfo portActionInfo = null;
ArrayList<ActionInfo> listActionInfo = new ArrayList<>();
ArrayList<InstructionInfo> instructionInfo = new ArrayList<>();
switch(tableId) {
case NwConstants.OUTBOUND_NAPT_TABLE:
ipActionInfo = new ActionSetSourceIp(ipAddress);
// Added External Gateway MAC Address
macActionInfo = new ActionSetFieldEthernetSource(new MacAddress(extGwMacAddress));
if (protocol == NAPTEntryEvent.Protocol.TCP) {
portActionInfo = new ActionSetTcpSourcePort(port);
} else if (protocol == NAPTEntryEvent.Protocol.UDP) {
portActionInfo = new ActionSetUdpSourcePort(port);
}
// reset the split-horizon bit to allow traffic from tunnel to be sent back to the provider port
instructionInfo.add(new InstructionWriteMetadata(MetaDataUtil.getVpnIdMetadata(vpnId.longValue()), Uint64.fromLongBits(MetaDataUtil.METADATA_MASK_VRFID.longValue() | MetaDataUtil.METADATA_MASK_SH_FLAG.longValue())));
break;
case NwConstants.INBOUND_NAPT_TABLE:
ipActionInfo = new ActionSetDestinationIp(ipAddress);
if (protocol == NAPTEntryEvent.Protocol.TCP) {
portActionInfo = new ActionSetTcpDestinationPort(port);
} else if (protocol == NAPTEntryEvent.Protocol.UDP) {
portActionInfo = new ActionSetUdpDestinationPort(port);
}
instructionInfo.add(new InstructionWriteMetadata(MetaDataUtil.getVpnIdMetadata(segmentId.longValue()), MetaDataUtil.METADATA_MASK_VRFID));
break;
default:
LOG.error("buildAndGetSetActionInstructionInfo : Neither OUTBOUND_NAPT_TABLE nor " + "INBOUND_NAPT_TABLE matches with input table id {}", tableId);
return Collections.emptyList();
}
listActionInfo.add(ipActionInfo);
listActionInfo.add(portActionInfo);
if (macActionInfo != null) {
listActionInfo.add(macActionInfo);
LOG.debug("buildAndGetSetActionInstructionInfo : External GW MAC Address {} is found ", macActionInfo);
}
instructionInfo.add(new InstructionApplyActions(listActionInfo));
instructionInfo.add(new InstructionGotoTable(NwConstants.NAPT_PFIB_TABLE));
return instructionInfo;
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.sr.rev130819.SegmentId in project netvirt by opendaylight.
the class NaptManager method removeIntExtIpMapDS.
protected void removeIntExtIpMapDS(Uint32 segmentId, String internalIp) {
InstanceIdentifierBuilder<IpMap> idBuilder = InstanceIdentifier.builder(IntextIpMap.class).child(IpMapping.class, new IpMappingKey(segmentId)).child(IpMap.class, new IpMapKey(internalIp));
InstanceIdentifier<IpMap> id = idBuilder.build();
LOG.debug("removeIntExtIpMapDS : Removing ipmap from datastore");
MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
}
Aggregations