2 * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
10 * Created eyugsar 2016/12/1
13 package org.opendaylight.vpnservice.natservice.internal;
16 import java.util.ArrayList;
17 import java.util.Arrays;
18 import java.util.List;
19 import java.util.concurrent.Future;
20 import java.util.concurrent.ExecutionException;
22 import com.google.common.collect.Lists;
23 import org.apache.commons.net.util.SubnetUtils;
24 import org.apache.commons.net.util.SubnetUtils.SubnetInfo;
25 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
26 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
27 import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.AllocateIdInput;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.AllocateIdInputBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.AllocateIdOutput;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.CreateIdPoolInput;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.CreateIdPoolInputBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.ReleaseIdInput;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.ReleaseIdInputBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.IntextIpMap;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.IntextIpPortMap;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.ProtocolTypes;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.SnatintIpPortMap;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.floating.ip.info.router.ports.Ports;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.floating.ip.info.router.ports.PortsBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.map.IpMapping;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.map.IpMappingKey;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.map.ip.mapping.IpMap;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.map.ip.mapping.IpMapBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.map.ip.mapping.IpMapKey;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.port.map.IpPortMapping;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.port.map.IpPortMappingKey;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolType;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolTypeKey;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMap;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMapBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMapKey;
54 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;
55 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.IpPortExternalBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.router.id.name.RouterIds;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.snatint.ip.port.map.IntipPortMap;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.snatint.ip.port.map.IntipPortMapKey;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPort;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPortKey;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoType;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoTypeBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoTypeKey;
64 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
65 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
66 import org.opendaylight.yangtools.yang.common.RpcResult;
67 import org.slf4j.Logger;
68 import org.slf4j.LoggerFactory;
70 import com.google.common.base.Optional;
71 import com.google.common.util.concurrent.UncheckedExecutionException;
73 public class NaptManager {
74 private static final Logger LOG = LoggerFactory.getLogger(NaptManager.class);
75 private final DataBroker broker;
76 private IdManagerService idManager;
77 private static final long LOW_PORT = 49152L;
78 private static final long HIGH_PORT = 65535L;
79 private static boolean EXTSUBNET_FLAG = false;
80 private static boolean NEXT_EXTIP_FLAG = false;
82 public NaptManager(final DataBroker db) {
86 public void setIdManager(IdManagerService idManager) {
87 this.idManager = idManager;
90 protected void createNaptPortPool(String PoolName) {
91 LOG.debug("NAPT Service : createPortPool requested for : {}", PoolName);
92 CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
93 .setPoolName(PoolName)
98 Future<RpcResult<Void>> result = idManager.createIdPool(createPool);
99 if ((result != null) && (result.get().isSuccessful())) {
100 LOG.debug("NAPT Service : Created PortPool");
102 LOG.error("NAPT Service : Unable to create PortPool");
104 } catch (InterruptedException | ExecutionException e) {
105 LOG.error("Failed to create PortPool for NAPT Service",e);
109 // 1. napt service functions
111 * this method is used to inform this service of what external IP address to be used
112 * as mapping when requested one for the internal IP address given in the input
113 * @param segmentId – segmentation in which the mapping to be used. Eg; routerid
114 * @param internal subnet prefix or ip address
115 * @param external subnet prefix or ip address
118 public void registerMapping(long segmentId, IPAddress internal, IPAddress external) {
120 LOG.debug("NAPT Service : registerMapping called with segmentid {}, internalIp {}, prefix {}, externalIp {} and prefix {} ", segmentId, internal.getIpAddress(),
121 internal.getPrefixLength(), external.getIpAddress(), external.getPrefixLength());
122 // Create Pool per ExternalIp and not for all IPs in the subnet. Create new Pools during getExternalAddressMapping if exhausted.
123 String externalIpPool;
124 if (external.getPrefixLength() !=0 && external.getPrefixLength() != NatConstants.DEFAULT_PREFIX) { // subnet case
125 String externalSubnet = new StringBuilder(64).append(external.getIpAddress()).append("/").append(external.getPrefixLength()).toString();
126 LOG.debug("NAPT Service : externalSubnet is : {}", externalSubnet);
127 SubnetUtils subnetUtils = new SubnetUtils(externalSubnet);
128 SubnetInfo subnetInfo = subnetUtils.getInfo();
129 externalIpPool = subnetInfo.getLowAddress();
131 externalIpPool = external.getIpAddress();
133 createNaptPortPool(externalIpPool);
135 // Store the ip to ip map in Operational DS
136 String internalIp = internal.getIpAddress();
137 if(internal.getPrefixLength() != 0) {
138 internalIp = new StringBuilder(64).append(internal.getIpAddress()).append("/").append(internal.getPrefixLength()).toString();
140 String externalIp = external.getIpAddress();
141 if(external.getPrefixLength() != 0) {
142 externalIp = new StringBuilder(64).append(external.getIpAddress()).append("/").append(external.getPrefixLength()).toString();
144 IpMap ipm = new IpMapBuilder().setKey(new IpMapKey(internalIp)).setInternalIp(internalIp).setExternalIp(externalIp).build();
145 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, getIpMapIdentifier(segmentId, internalIp), ipm);
146 LOG.debug("NAPT Service : registerMapping exit after updating DS with internalIP {}, externalIP {}", internalIp, externalIp);
151 * method to get external ip/port mapping when provided with internal ip/port pair
152 * If already a mapping exist for the given input, then the existing mapping is returned
153 * instead of overwriting with new ip/port pair.
155 * @param sourceAddress - internal ip address/port pair
156 * @return external ip address/port
158 public SessionAddress getExternalAddressMapping(long segmentId, SessionAddress sourceAddress, NAPTEntryEvent.Protocol protocol) {
159 LOG.debug("NAPT Service : getExternalAddressMapping called with segmentId {}, internalIp {} and port {}",
160 segmentId, sourceAddress.getIpAddress(), sourceAddress.getPortNumber());
162 1. Get Internal IP, Port in IP:Port format
163 2. Inside DB with routerId get the list of entries and check if it matches with existing IP:Port
164 3. If True return SessionAddress of ExternalIp and Port
165 4. Else check ip Map and Form the ExternalIp and Port and update DB and then return ExternalIp and Port
168 //SessionAddress externalIpPort = new SessionAddress();
169 String internalIpPort = new StringBuilder(64).append(sourceAddress.getIpAddress()).append(":").append(sourceAddress.getPortNumber()).toString();
171 // First check existing Port Map.
172 SessionAddress existingIpPort = checkIpPortMap(segmentId, internalIpPort ,protocol);
173 if(existingIpPort != null) {
174 // populate externalIpPort from IpPortMap and return
175 LOG.debug("NAPT Service : getExternalAddressMapping successfully returning existingIpPort as {} and {}", existingIpPort.getIpAddress(), existingIpPort.getPortNumber());
176 return existingIpPort;
178 // Now check in ip-map
179 String externalIp = checkIpMap(segmentId, sourceAddress.getIpAddress());
180 if(externalIp == null) {
181 LOG.error("NAPT Service : getExternalAddressMapping, Unexpected error, internal to external ip map does not exist");
184 /* Logic assuming internalIp is always ip and not subnet
185 * case 1: externalIp is ip
186 * a) goto externalIp pool and getPort and return
187 * b) else return error
188 * case 2: externalIp is subnet
189 * a) Take first externalIp and goto that Pool and getPort
191 * else Take second externalIp and create that Pool and getPort
194 * Continue same with third externalIp till we exhaust subnet
195 * b) Nothing worked return error
197 SubnetUtils externalIpSubnet;
198 List<String> allIps = new ArrayList<String>();
199 String subnetPrefix = "/" + String.valueOf(NatConstants.DEFAULT_PREFIX);
200 if( !externalIp.contains(subnetPrefix) ) {
201 EXTSUBNET_FLAG = true;
202 externalIpSubnet = new SubnetUtils(externalIp);
203 allIps = Arrays.asList(externalIpSubnet.getInfo().getAllAddresses());
204 LOG.debug("NAPT Service : total count of externalIps available {}", externalIpSubnet.getInfo().getAddressCount());
206 LOG.debug("NAPT Service : getExternalAddress single ip case");
207 if(externalIp.contains(subnetPrefix)) {
208 String[] externalIpSplit = externalIp.split("/");
209 String extIp = externalIpSplit[0];
210 externalIp = extIp; //remove /32 what we got from checkIpMap
212 allIps.add(externalIp);
215 for(String extIp : allIps) {
216 LOG.info("NAPT Service : Looping externalIPs with externalIP now as {}", extIp);
217 if(NEXT_EXTIP_FLAG) {
218 createNaptPortPool(extIp);
219 LOG.debug("NAPT Service : Created Pool for next Ext IP {}", extIp);
221 AllocateIdInput getIdInput = new AllocateIdInputBuilder()
222 .setPoolName(extIp).setIdKey(internalIpPort)
225 Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
226 RpcResult<AllocateIdOutput> rpcResult;
227 if ((result != null) && (result.get().isSuccessful())) {
228 LOG.debug("NAPT Service : Got id from idManager");
229 rpcResult = result.get();
231 LOG.error("NAPT Service : getExternalAddressMapping, idManager could not allocate id retry if subnet");
232 if(!EXTSUBNET_FLAG) {
233 LOG.error("NAPT Service : getExternalAddressMapping returning null for single IP case, may be ports exhausted");
236 LOG.debug("NAPT Service : Could be ports exhausted case, try with another externalIP if possible");
237 NEXT_EXTIP_FLAG = true;
240 int extPort= rpcResult.getResult().getIdValue().intValue();
241 SessionAddress externalIpPort = new SessionAddress(extIp, extPort);
242 // Write to ip-port-map before returning
243 IpPortExternalBuilder ipExt = new IpPortExternalBuilder();
244 IpPortExternal ipPortExt = ipExt.setIpAddress(extIp).setPortNum(extPort).build();
245 IpPortMap ipm = new IpPortMapBuilder().setKey(new IpPortMapKey(internalIpPort))
246 .setIpPortInternal(internalIpPort).setIpPortExternal(ipPortExt).build();
247 LOG.debug("NAPT Service : getExternalAddressMapping writing into ip-port-map with externalIP {} and port {}",
248 ipPortExt.getIpAddress(), ipPortExt.getPortNum());
250 MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION,
251 getIpPortMapIdentifier(segmentId, internalIpPort, protocol), ipm);
252 } catch (UncheckedExecutionException uee) {
253 LOG.error("NAPT Service : Failed to write into ip-port-map with exception {}", uee.getMessage() );
256 // Write to snat-internal-ip-port-info
257 String internalIpAddress = sourceAddress.getIpAddress();
258 int ipPort = sourceAddress.getPortNumber();
259 ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
260 List<Integer> portList = NatUtil.getInternalIpPortListInfo(broker,segmentId,internalIpAddress,protocolType);
261 if (portList == null) {
262 portList = Lists.newArrayList();
264 portList.add(ipPort);
266 IntIpProtoTypeBuilder builder = new IntIpProtoTypeBuilder();
267 IntIpProtoType intIpProtocolType = builder.setKey(new IntIpProtoTypeKey(protocolType)).setPorts(portList).build();
269 MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, NatUtil.buildSnatIntIpPortIdentifier(segmentId, internalIpAddress, protocolType), intIpProtocolType);
270 } catch (Exception ex) {
271 LOG.error("NAPT Service : Failed to write into snat-internal-ip-port-info with exception {}", ex.getMessage() );
274 LOG.debug("NAPT Service : getExternalAddressMapping successfully returning externalIP {} and port {}",
275 externalIpPort.getIpAddress(), externalIpPort.getPortNumber());
276 return externalIpPort;
277 } catch(InterruptedException | ExecutionException e) {
278 LOG.error("NAPT Service : getExternalAddressMapping, Exception caught {}",e);
282 }// end of else ipmap present
283 }// end of else check ipmap
284 LOG.error("NAPT Service: getExternalAddressMapping returning null, nothing worked or externalIPs exhausted");
290 * release the existing mapping of internal ip/port to external ip/port pair
291 * if no mapping exist for given internal ip/port, it returns false
294 * @return true if mapping exist and the mapping is removed successfully
297 public boolean releaseAddressMapping(long segmentId, SessionAddress address, NAPTEntryEvent.Protocol protocol) {
299 LOG.debug("NAPT Service : releaseAddressMapping called with segmentId {}, internalIP {}, port {}", segmentId, address.getIpAddress(), address.getPortNumber());
300 // delete entry from IpPort Map and IP Map if exists
301 String internalIpPort = new StringBuilder(64).append(address.getIpAddress()).append(":").append(address.getPortNumber()).toString();
302 SessionAddress existingIpPort = checkIpPortMap(segmentId, internalIpPort, protocol);
303 if(existingIpPort != null) {
304 // delete the entry from IpPortMap DS
306 removeFromIpPortMapDS(segmentId, internalIpPort , protocol);
307 } catch (Exception e){
308 LOG.error("NAPT Service : releaseAddressMapping failed, Removal of ipportmap {} for router {} failed {}" , internalIpPort, segmentId, e);
312 LOG.error("NAPT Service : releaseAddressMapping failed, segmentId {} and internalIpPort {} not found in IpPortMap DS", segmentId, internalIpPort);
315 String existingIp = checkIpMap(segmentId, address.getIpAddress());
316 if(existingIp != null) {
317 // delete the entry from IpMap DS
319 removeFromIpMapDS(segmentId, address.getIpAddress());
320 } catch (Exception e){
321 LOG.error("NAPT Service : Removal of ipmap {} for router {} failed {}" , address.getIpAddress(), segmentId, e);
324 //delete the entry from snatIntIpportinfo
326 removeFromSnatIpPortDS(segmentId, address.getIpAddress());
327 } catch (Exception e){
328 LOG.error("NAPT Service : releaseAddressMapping failed, Removal of snatipportmap {} for router {} failed {}" , address.getIpAddress(), segmentId, e);
332 LOG.error("NAPT Service : releaseAddressMapping failed, segmentId {} and internalIpPort {} not found in IpMap DS", segmentId, internalIpPort);
335 // Finally release port from idmanager
336 removePortFromPool(internalIpPort, existingIpPort.getIpAddress());
338 LOG.debug("NAPT Service : Exit of releaseAddressMapping successfully for segmentId {} and internalIpPort {}", segmentId, internalIpPort);
343 protected void releaseIpExtPortMapping(long segmentId, SessionAddress address, NAPTEntryEvent.Protocol protocol) {
344 String internalIpPort = address.getIpAddress() + ":" + address.getPortNumber();
345 SessionAddress existingIpPort = checkIpPortMap(segmentId, internalIpPort, protocol);
346 if(existingIpPort != null) {
347 // delete the entry from IpPortMap DS
349 removeFromIpPortMapDS(segmentId, internalIpPort , protocol);
350 // Finally release port from idmanager
351 removePortFromPool(internalIpPort, existingIpPort.getIpAddress());
352 } catch (Exception e){
353 LOG.error("NAPT Service : releaseAddressMapping failed, Removal of ipportmap {} for router {} failed {}" ,
354 internalIpPort, segmentId, e);
357 LOG.error("NAPT Service : releaseIpExtPortMapping failed, segmentId {} and internalIpPort {} not found in IpPortMap DS", segmentId, internalIpPort);
360 //delete the entry of port for InternalIp from snatIntIpportMappingDS
362 removeSnatIntIpPortDS(segmentId,address, protocol);
363 } catch (Exception e){
364 LOG.error("NAPT Service : releaseSnatIpPortMapping failed, Removal of snatipportmap {} for router {} failed {}" ,
365 address.getIpAddress(), segmentId, e);
370 * removes the internal ip to external ip mapping if present
372 * @return true if successfully removed
374 public boolean removeMapping(long segmentId) {
376 removeIpMappingForRouterID(segmentId);
377 } catch (Exception e){
378 LOG.error("NAPT Service : Removal of IPMapping for router {} failed {}" , segmentId, e);
382 //TODO : This is when router is deleted then cleanup the entries in tables, ports etc - Delete scenarios
386 // 2. Utility functions
387 protected InstanceIdentifier<IpMap> getIpMapIdentifier(long segid, String internal) {
388 InstanceIdentifier<IpMap> id = InstanceIdentifier.builder(
389 IntextIpMap.class).child(IpMapping.class, new IpMappingKey(segid)).child(IpMap.class, new IpMapKey(internal)).build();
393 public static List<IpMap> getIpMapList(DataBroker broker, Long routerId) {
394 InstanceIdentifier id = getIpMapList(routerId);
395 Optional<IpMapping> ipMappingListData = NatUtil.read(broker, LogicalDatastoreType.OPERATIONAL, id);
396 if (ipMappingListData.isPresent()) {
397 IpMapping ipMapping = ipMappingListData.get();
398 return ipMapping.getIpMap();
403 protected static InstanceIdentifier<IpMapping> getIpMapList(long routerId) {
404 InstanceIdentifier<IpMapping> id = InstanceIdentifier.builder(
405 IntextIpMap.class).child(IpMapping.class, new IpMappingKey(routerId)).build();
409 protected InstanceIdentifier<IpPortMap> getIpPortMapIdentifier(long segid, String internal, NAPTEntryEvent.Protocol protocol) {
410 ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
411 InstanceIdentifier<IpPortMap> id = InstanceIdentifier.builder(
412 IntextIpPortMap.class).child(IpPortMapping.class, new IpPortMappingKey(segid)).child(IntextIpProtocolType.class, new IntextIpProtocolTypeKey(protocolType)).
413 child(IpPortMap.class, new IpPortMapKey(internal)).build();
417 protected SessionAddress checkIpPortMap(long segmentId, String internalIpPort, NAPTEntryEvent.Protocol protocol) {
419 LOG.debug("NAPT Service : checkIpPortMap called with segmentId {} and internalIpPort {}", segmentId, internalIpPort);
420 ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
421 // check if ip-port-map node is there
422 InstanceIdentifierBuilder<IntextIpProtocolType> idBuilder =
423 InstanceIdentifier.builder(IntextIpPortMap.class).child(IpPortMapping.class, new IpPortMappingKey(segmentId)).child(IntextIpProtocolType.class, new IntextIpProtocolTypeKey(protocolType));
424 InstanceIdentifier<IntextIpProtocolType> id = idBuilder.build();
425 Optional<IntextIpProtocolType> intextIpProtocolType = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id);
426 if (intextIpProtocolType.isPresent()) {
427 List<IpPortMap> ipPortMaps = intextIpProtocolType.get().getIpPortMap();
428 for (IpPortMap ipPortMap : ipPortMaps) {
429 if (ipPortMap.getIpPortInternal().equals(internalIpPort)) {
430 LOG.debug("NAPT Service : IpPortMap : {}", ipPortMap);
431 SessionAddress externalIpPort = new SessionAddress(ipPortMap.getIpPortExternal().getIpAddress(),
432 ipPortMap.getIpPortExternal().getPortNum());
433 LOG.debug("NAPT Service : checkIpPortMap returning successfully externalIP {} and port {}",
434 externalIpPort.getIpAddress(), externalIpPort.getPortNumber());
435 return externalIpPort;
439 // return null if not found
440 LOG.error("NAPT Service : no-entry in checkIpPortMap, returning NULL [should be OK] for segmentId {} and internalIPPort {}", segmentId, internalIpPort);
444 protected String checkIpMap(long segmentId, String internalIp) {
446 LOG.debug("NAPT Service : checkIpMap called with segmentId {} and internalIp {}", segmentId, internalIp);
448 // check if ip-map node is there
449 InstanceIdentifierBuilder<IpMapping> idBuilder =
450 InstanceIdentifier.builder(IntextIpMap.class).child(IpMapping.class, new IpMappingKey(segmentId));
451 InstanceIdentifier<IpMapping> id = idBuilder.build();
452 Optional<IpMapping> ipMapping = MDSALUtil.read(broker, LogicalDatastoreType.OPERATIONAL, id);
453 if (ipMapping.isPresent()) {
454 List<IpMap> ipMaps = ipMapping.get().getIpMap();
455 for (IpMap ipMap : ipMaps) {
456 if (ipMap.getInternalIp().equals(internalIp)) {
457 LOG.debug("NAPT Service : IpMap : {}", ipMap);
458 externalIp = ipMap.getExternalIp().toString();
459 LOG.debug("NAPT Service : checkIpMap successfully returning externalIp {}", externalIp );
461 } else if (ipMap.getInternalIp().contains("/")) { // subnet case
462 SubnetUtils subnetUtils = new SubnetUtils(ipMap.getInternalIp());
463 SubnetInfo subnetInfo = subnetUtils.getInfo();
464 if (subnetInfo.isInRange(internalIp)) {
465 LOG.debug("NAPT Service : internalIp {} found to be IpMap of internalIpSubnet {}", internalIp, ipMap.getInternalIp());
466 externalIp = ipMap.getExternalIp().toString();
467 LOG.debug("NAPT Service : checkIpMap successfully returning externalIp {}", externalIp );
473 // return null if not found
474 LOG.error("NAPT Service : checkIpMap failed, returning NULL for segmentId {} and internalIp {}", segmentId, internalIp);
478 protected void removeSnatIntIpPortDS(long segmentId, SessionAddress address,NAPTEntryEvent.Protocol protocol) {
479 LOG.trace("NAPT Service : removeSnatIntIpPortDS method called for IntIpport {} of router {} ",address,segmentId);
480 ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
481 List<Integer> portList = NatUtil.getInternalIpPortListInfo(broker,segmentId,address.getIpAddress(),protocolType);
482 if (portList == null || portList.isEmpty() || !portList.contains(address.getPortNumber())) {
483 LOG.debug("Internal IP {} for port {} entry not found in SnatIntIpPort DS",address.getIpAddress(),address.getPortNumber());
486 LOG.trace("NAPT Service : PortList {} retrieved for InternalIp {} of router {}",portList,address.getIpAddress(),segmentId);
487 Integer port = address.getPortNumber();
488 portList.remove(port);
490 IntIpProtoTypeBuilder builder = new IntIpProtoTypeBuilder();
491 IntIpProtoType intIpProtocolType = builder.setKey(new IntIpProtoTypeKey(protocolType)).setPorts(portList).build();
493 MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, NatUtil.buildSnatIntIpPortIdentifier(segmentId, address.getIpAddress(), protocolType), intIpProtocolType);
494 } catch (Exception ex) {
495 LOG.error("NAPT Service : Failed to write into snat-internal-ip-port-info with exception {}", ex.getMessage() );
497 LOG.debug("NAPT Service : Removing SnatIp {} Port {} of router {} from SNATIntIpport datastore : {}"
498 ,address.getIpAddress(),address.getPortNumber(),segmentId);
501 protected void removeFromSnatIpPortDS(long segmentId, String internalIp) {
502 InstanceIdentifier<IpPort> intIp = InstanceIdentifier.builder(SnatintIpPortMap.class).child
503 (IntipPortMap.class, new IntipPortMapKey(segmentId)).child(IpPort.class, new IpPortKey(internalIp)).build();
504 // remove from SnatIpPortDS
505 LOG.debug("NAPT Service : Removing SnatIpPort from datastore : {}", intIp);
506 MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, intIp);
510 protected void removeFromIpPortMapDS(long segmentId, String internalIpPort, NAPTEntryEvent.Protocol protocol) {
511 ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
512 InstanceIdentifierBuilder<IpPortMap> idBuilder = InstanceIdentifier.builder(IntextIpPortMap.class)
513 .child(IpPortMapping.class, new IpPortMappingKey(segmentId)).child(IntextIpProtocolType.class, new IntextIpProtocolTypeKey(protocolType))
514 .child(IpPortMap.class, new IpPortMapKey(internalIpPort));
515 InstanceIdentifier<IpPortMap> id = idBuilder.build();
516 // remove from ipportmap DS
517 LOG.debug("NAPT Service : Removing ipportmap from datastore : {}", id);
518 MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, id);
521 protected void removeFromIpMapDS(long segmentId, String internalIp) {
522 InstanceIdentifierBuilder<IpMap> idBuilder = InstanceIdentifier.builder(IntextIpMap.class)
523 .child(IpMapping.class, new IpMappingKey(segmentId))
524 .child(IpMap.class, new IpMapKey(internalIp));
525 InstanceIdentifier<IpMap> id = idBuilder.build();
526 // remove from ipmap DS
527 LOG.debug("NAPT Service : Removing ipmap from datastore : {}", id);
528 MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, id);
531 private void removeIpMappingForRouterID(long segmentId) {
532 InstanceIdentifierBuilder<IpMapping> idBuilder = InstanceIdentifier.builder(IntextIpMap.class)
533 .child(IpMapping.class, new IpMappingKey(segmentId));
534 InstanceIdentifier<IpMapping> id = idBuilder.build();
535 // remove from ipmap DS
536 LOG.debug("NAPT Service : Removing ipmap from datastore : {}", id);
537 MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, id);
540 protected void removePortFromPool(String internalIpPort, String externalIp) {
541 LOG.debug("NAPT Service : removePortFromPool method called");
542 ReleaseIdInput idInput = new ReleaseIdInputBuilder().
543 setPoolName(externalIp)
544 .setIdKey(internalIpPort).build();
546 Future<RpcResult<Void>> result = idManager.releaseId(idInput);
547 RpcResult<Void> rpcResult = result.get();
548 if(!rpcResult.isSuccessful()) {
549 LOG.error("NAPT Service : idmanager failed to remove port from pool {}", rpcResult.getErrors());
551 LOG.debug("NAPT Service : Removed port from pool for InternalIpPort {} with externalIp {}",internalIpPort,externalIp);
552 } catch (InterruptedException | ExecutionException e) {
553 LOG.error("NAPT Service : idmanager failed with Exception {} when removing entry in pool with key {}, ", e, internalIpPort);