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.netvirt.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.genius.mdsalutil.MDSALUtil;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.*;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.*;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCounters;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCountersKey;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.external.counters.ExternalIpCounter;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.external.counters.ExternalIpCounterKey;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.IpMapping;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.IpMappingKey;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.ip.mapping.IpMap;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.ip.mapping.IpMapBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.ip.mapping.IpMapKey;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMapping;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMappingKey;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolType;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolTypeKey;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMap;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMapBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMapKey;
47 import 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;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.ip.port.map.IpPortExternalBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMap;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMapKey;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPort;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPortKey;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoType;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoTypeBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoTypeKey;
56 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
57 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
58 import org.opendaylight.yangtools.yang.common.RpcResult;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.external.counters.ExternalIpCounterBuilder;
63 import com.google.common.base.Optional;
64 import com.google.common.util.concurrent.UncheckedExecutionException;
66 public class NaptManager {
67 private static final Logger LOG = LoggerFactory.getLogger(NaptManager.class);
68 private final DataBroker broker;
69 private IdManagerService idManager;
70 private static final long LOW_PORT = 49152L;
71 private static final long HIGH_PORT = 65535L;
72 private static boolean EXTSUBNET_FLAG = false;
73 private static boolean NEXT_EXTIP_FLAG = false;
75 public NaptManager(final DataBroker db) {
79 public void setIdManager(IdManagerService idManager) {
80 this.idManager = idManager;
83 protected void createNaptPortPool(String PoolName) {
84 LOG.debug("NAPT Service : createPortPool requested for : {}", PoolName);
85 CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
86 .setPoolName(PoolName)
91 Future<RpcResult<Void>> result = idManager.createIdPool(createPool);
92 if ((result != null) && (result.get().isSuccessful())) {
93 LOG.debug("NAPT Service : Created PortPool");
95 LOG.error("NAPT Service : Unable to create PortPool");
97 } catch (InterruptedException | ExecutionException e) {
98 LOG.error("Failed to create PortPool for NAPT Service",e);
102 void removeNaptPortPool(String poolName) {
103 DeleteIdPoolInput deleteIdPoolInput = new DeleteIdPoolInputBuilder().setPoolName(poolName).build();
104 LOG.debug("NAPT Service : Remove Napt port pool requested for : {}", poolName);
106 Future<RpcResult<Void>> result = idManager.deleteIdPool(deleteIdPoolInput);
107 if ((result != null) && (result.get().isSuccessful())) {
108 LOG.debug("NAPT Service : Deleted PortPool {}", poolName);
110 LOG.error("NAPT Service : Unable to delete PortPool {}", poolName);
112 } catch (InterruptedException | ExecutionException e) {
113 LOG.error("Failed to delete PortPool {} for NAPT Service", poolName, e);
117 // 1. napt service functions
119 * this method is used to inform this service of what external IP address to be used
120 * as mapping when requested one for the internal IP address given in the input
121 * @param segmentId – segmentation in which the mapping to be used. Eg; routerid
122 * @param internal subnet prefix or ip address
123 * @param external subnet prefix or ip address
126 public void registerMapping(long segmentId, IPAddress internal, IPAddress external) {
128 LOG.debug("NAPT Service : registerMapping called with segmentid {}, internalIp {}, prefix {}, externalIp {} and prefix {} ", segmentId, internal.getIpAddress(),
129 internal.getPrefixLength(), external.getIpAddress(), external.getPrefixLength());
130 // Create Pool per ExternalIp and not for all IPs in the subnet. Create new Pools during getExternalAddressMapping if exhausted.
131 String externalIpPool;
132 if (external.getPrefixLength() !=0 && external.getPrefixLength() != NatConstants.DEFAULT_PREFIX) { // subnet case
133 String externalSubnet = new StringBuilder(64).append(external.getIpAddress()).append("/").append(external.getPrefixLength()).toString();
134 LOG.debug("NAPT Service : externalSubnet is : {}", externalSubnet);
135 SubnetUtils subnetUtils = new SubnetUtils(externalSubnet);
136 SubnetInfo subnetInfo = subnetUtils.getInfo();
137 externalIpPool = subnetInfo.getLowAddress();
139 externalIpPool = external.getIpAddress();
141 createNaptPortPool(externalIpPool);
143 // Store the ip to ip map in Operational DS
144 String internalIp = internal.getIpAddress();
145 if(internal.getPrefixLength() != 0) {
146 internalIp = new StringBuilder(64).append(internal.getIpAddress()).append("/").append(internal.getPrefixLength()).toString();
148 String externalIp = external.getIpAddress();
149 if(external.getPrefixLength() != 0) {
150 externalIp = new StringBuilder(64).append(external.getIpAddress()).append("/").append(external.getPrefixLength()).toString();
152 updateCounter(segmentId, externalIp, true);
153 //update the actual ip-map
154 IpMap ipm = new IpMapBuilder().setKey(new IpMapKey(internalIp)).setInternalIp(internalIp).setExternalIp(externalIp).build();
155 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, getIpMapIdentifier(segmentId, internalIp), ipm);
156 LOG.debug("NAPT Service : registerMapping exit after updating DS with internalIP {}, externalIP {}", internalIp, externalIp);
159 public void updateCounter(long segmentId, String externalIp, boolean isAdd){
161 InstanceIdentifier<ExternalIpCounter> id = InstanceIdentifier.builder(ExternalIpsCounter.class).child(ExternalCounters.class, new ExternalCountersKey(segmentId)).child(ExternalIpCounter.class, new ExternalIpCounterKey(externalIp)).build();
162 Optional <ExternalIpCounter> externalIpCounter = MDSALUtil.read(broker, LogicalDatastoreType.OPERATIONAL, id);
163 if (externalIpCounter.isPresent()) {
164 counter = externalIpCounter.get().getCounter();
167 LOG.debug("NAT Service : externalIp and counter after increment are {} and {}", externalIp, counter);
172 LOG.debug("NAT Service : externalIp and counter after decrement are {} and {}", externalIp, counter);
179 //update the new counter value for this externalIp
180 ExternalIpCounter externalIpCounterData = new ExternalIpCounterBuilder().setKey(new ExternalIpCounterKey(externalIp)).setExternalIp(externalIp).setCounter(counter).build();
181 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, getExternalIpsIdentifier(segmentId, externalIp), externalIpCounterData);
186 * method to get external ip/port mapping when provided with internal ip/port pair
187 * If already a mapping exist for the given input, then the existing mapping is returned
188 * instead of overwriting with new ip/port pair.
190 * @param sourceAddress - internal ip address/port pair
191 * @return external ip address/port
193 public SessionAddress getExternalAddressMapping(long segmentId, SessionAddress sourceAddress, NAPTEntryEvent.Protocol protocol) {
194 LOG.debug("NAPT Service : getExternalAddressMapping called with segmentId {}, internalIp {} and port {}",
195 segmentId, sourceAddress.getIpAddress(), sourceAddress.getPortNumber());
197 1. Get Internal IP, Port in IP:Port format
198 2. Inside DB with routerId get the list of entries and check if it matches with existing IP:Port
199 3. If True return SessionAddress of ExternalIp and Port
200 4. Else check ip Map and Form the ExternalIp and Port and update DB and then return ExternalIp and Port
203 //SessionAddress externalIpPort = new SessionAddress();
204 String internalIpPort = new StringBuilder(64).append(sourceAddress.getIpAddress()).append(":").append(sourceAddress.getPortNumber()).toString();
206 // First check existing Port Map.
207 SessionAddress existingIpPort = checkIpPortMap(segmentId, internalIpPort, protocol);
208 if(existingIpPort != null) {
209 // populate externalIpPort from IpPortMap and return
210 LOG.debug("NAPT Service : getExternalAddressMapping successfully returning existingIpPort as {} and {}", existingIpPort.getIpAddress(), existingIpPort.getPortNumber());
211 return existingIpPort;
213 // Now check in ip-map
214 String externalIp = checkIpMap(segmentId, sourceAddress.getIpAddress());
215 if(externalIp == null) {
216 LOG.error("NAPT Service : getExternalAddressMapping, Unexpected error, internal to external ip map does not exist");
219 /* Logic assuming internalIp is always ip and not subnet
220 * case 1: externalIp is ip
221 * a) goto externalIp pool and getPort and return
222 * b) else return error
223 * case 2: externalIp is subnet
224 * a) Take first externalIp and goto that Pool and getPort
226 * else Take second externalIp and create that Pool and getPort
229 * Continue same with third externalIp till we exhaust subnet
230 * b) Nothing worked return error
232 SubnetUtils externalIpSubnet;
233 List<String> allIps = new ArrayList<String>();
234 String subnetPrefix = "/" + String.valueOf(NatConstants.DEFAULT_PREFIX);
235 if( !externalIp.contains(subnetPrefix) ) {
236 EXTSUBNET_FLAG = true;
237 externalIpSubnet = new SubnetUtils(externalIp);
238 allIps = Arrays.asList(externalIpSubnet.getInfo().getAllAddresses());
239 LOG.debug("NAPT Service : total count of externalIps available {}", externalIpSubnet.getInfo().getAddressCount());
241 LOG.debug("NAPT Service : getExternalAddress single ip case");
242 if(externalIp.contains(subnetPrefix)) {
243 String[] externalIpSplit = externalIp.split("/");
244 String extIp = externalIpSplit[0];
245 externalIp = extIp; //remove /32 what we got from checkIpMap
247 allIps.add(externalIp);
250 for(String extIp : allIps) {
251 LOG.info("NAPT Service : Looping externalIPs with externalIP now as {}", extIp);
252 if(NEXT_EXTIP_FLAG) {
253 createNaptPortPool(extIp);
254 LOG.debug("NAPT Service : Created Pool for next Ext IP {}", extIp);
256 AllocateIdInput getIdInput = new AllocateIdInputBuilder()
257 .setPoolName(extIp).setIdKey(internalIpPort)
260 Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
261 RpcResult<AllocateIdOutput> rpcResult;
262 if ((result != null) && (result.get().isSuccessful())) {
263 LOG.debug("NAPT Service : Got id from idManager");
264 rpcResult = result.get();
266 LOG.error("NAPT Service : getExternalAddressMapping, idManager could not allocate id retry if subnet");
267 if(!EXTSUBNET_FLAG) {
268 LOG.error("NAPT Service : getExternalAddressMapping returning null for single IP case, may be ports exhausted");
271 LOG.debug("NAPT Service : Could be ports exhausted case, try with another externalIP if possible");
272 NEXT_EXTIP_FLAG = true;
275 int extPort= rpcResult.getResult().getIdValue().intValue();
276 SessionAddress externalIpPort = new SessionAddress(extIp, extPort);
277 // Write to ip-port-map before returning
278 IpPortExternalBuilder ipExt = new IpPortExternalBuilder();
279 IpPortExternal ipPortExt = ipExt.setIpAddress(extIp).setPortNum(extPort).build();
280 IpPortMap ipm = new IpPortMapBuilder().setKey(new IpPortMapKey(internalIpPort))
281 .setIpPortInternal(internalIpPort).setIpPortExternal(ipPortExt).build();
282 LOG.debug("NAPT Service : getExternalAddressMapping writing into ip-port-map with externalIP {} and port {}",
283 ipPortExt.getIpAddress(), ipPortExt.getPortNum());
285 MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION,
286 getIpPortMapIdentifier(segmentId, internalIpPort, protocol), ipm);
287 } catch (UncheckedExecutionException uee) {
288 LOG.error("NAPT Service : Failed to write into ip-port-map with exception {}", uee.getMessage() );
291 // Write to snat-internal-ip-port-info
292 String internalIpAddress = sourceAddress.getIpAddress();
293 int ipPort = sourceAddress.getPortNumber();
294 ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
295 List<Integer> portList = NatUtil.getInternalIpPortListInfo(broker,segmentId,internalIpAddress,protocolType);
296 if (portList == null) {
297 portList = Lists.newArrayList();
299 portList.add(ipPort);
301 IntIpProtoTypeBuilder builder = new IntIpProtoTypeBuilder();
302 IntIpProtoType intIpProtocolType = builder.setKey(new IntIpProtoTypeKey(protocolType)).setPorts(portList).build();
304 MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION,
305 NatUtil.buildSnatIntIpPortIdentifier(segmentId, internalIpAddress, protocolType), intIpProtocolType);
306 } catch (Exception ex) {
307 LOG.error("NAPT Service : Failed to write into snat-internal-ip-port-info with exception {}", ex.getMessage() );
310 LOG.debug("NAPT Service : getExternalAddressMapping successfully returning externalIP {} and port {}",
311 externalIpPort.getIpAddress(), externalIpPort.getPortNumber());
312 return externalIpPort;
313 } catch(InterruptedException | ExecutionException e) {
314 LOG.error("NAPT Service : getExternalAddressMapping, Exception caught {}",e);
318 }// end of else ipmap present
319 }// end of else check ipmap
320 LOG.error("NAPT Service: getExternalAddressMapping returning null, nothing worked or externalIPs exhausted");
326 * release the existing mapping of internal ip/port to external ip/port pair
327 * if no mapping exist for given internal ip/port, it returns false
330 * @return true if mapping exist and the mapping is removed successfully
333 public boolean releaseAddressMapping(long segmentId, SessionAddress address, NAPTEntryEvent.Protocol protocol) {
335 LOG.debug("NAPT Service : releaseAddressMapping called with segmentId {}, internalIP {}, port {}", segmentId, address.getIpAddress(), address.getPortNumber());
336 // delete entry from IpPort Map and IP Map if exists
337 String internalIpPort = new StringBuilder(64).append(address.getIpAddress()).append(":").append(address.getPortNumber()).toString();
338 SessionAddress existingIpPort = checkIpPortMap(segmentId, internalIpPort, protocol);
339 if(existingIpPort != null) {
340 // delete the entry from IpPortMap DS
342 removeFromIpPortMapDS(segmentId, internalIpPort , protocol);
343 } catch (Exception e){
344 LOG.error("NAPT Service : releaseAddressMapping failed, Removal of ipportmap {} for router {} failed {}" , internalIpPort, segmentId, e);
348 LOG.error("NAPT Service : releaseAddressMapping failed, segmentId {} and internalIpPort {} not found in IpPortMap DS", segmentId, internalIpPort);
351 String existingIp = checkIpMap(segmentId, address.getIpAddress());
352 if(existingIp != null) {
353 // delete the entry from IpMap DS
355 removeFromIpMapDS(segmentId, address.getIpAddress());
356 } catch (Exception e){
357 LOG.error("NAPT Service : Removal of ipmap {} for router {} failed {}" , address.getIpAddress(), segmentId, e);
360 //delete the entry from snatIntIpportinfo
362 removeFromSnatIpPortDS(segmentId, address.getIpAddress());
363 } catch (Exception e){
364 LOG.error("NAPT Service : releaseAddressMapping failed, Removal of snatipportmap {} for router {} failed {}" , address.getIpAddress(), segmentId, e);
368 LOG.error("NAPT Service : releaseAddressMapping failed, segmentId {} and internalIpPort {} not found in IpMap DS", segmentId, internalIpPort);
371 // Finally release port from idmanager
372 removePortFromPool(internalIpPort, existingIpPort.getIpAddress());
374 LOG.debug("NAPT Service : Exit of releaseAddressMapping successfully for segmentId {} and internalIpPort {}", segmentId, internalIpPort);
379 protected void releaseIpExtPortMapping(long segmentId, SessionAddress address, NAPTEntryEvent.Protocol protocol) {
380 String internalIpPort = address.getIpAddress() + ":" + address.getPortNumber();
381 SessionAddress existingIpPort = checkIpPortMap(segmentId, internalIpPort, protocol);
382 if(existingIpPort != null) {
383 // delete the entry from IpPortMap DS
385 removeFromIpPortMapDS(segmentId, internalIpPort , protocol);
386 // Finally release port from idmanager
387 removePortFromPool(internalIpPort, existingIpPort.getIpAddress());
388 } catch (Exception e){
389 LOG.error("NAPT Service : releaseAddressMapping failed, Removal of ipportmap {} for router {} failed {}" ,
390 internalIpPort, segmentId, e);
393 LOG.error("NAPT Service : releaseIpExtPortMapping failed, segmentId {} and internalIpPort {} not found in IpPortMap DS", segmentId, internalIpPort);
396 //delete the entry of port for InternalIp from snatIntIpportMappingDS
398 removeSnatIntIpPortDS(segmentId,address, protocol);
399 } catch (Exception e){
400 LOG.error("NAPT Service : releaseSnatIpPortMapping failed, Removal of snatipportmap {} for router {} failed {}" ,
401 address.getIpAddress(), segmentId, e);
406 * removes the internal ip to external ip mapping if present
408 * @return true if successfully removed
410 public boolean removeMapping(long segmentId) {
412 removeIpMappingForRouterID(segmentId);
413 removeIpPortMappingForRouterID(segmentId);
414 removeIntIpPortMappingForRouterID(segmentId);
415 } catch (Exception e){
416 LOG.error("NAPT Service : Removal of IPMapping for router {} failed {}" , segmentId, e);
420 //TODO : This is when router is deleted then cleanup the entries in tables, ports etc - Delete scenarios
424 // 2. Utility functions
425 protected InstanceIdentifier<IpMap> getIpMapIdentifier(long segid, String internal) {
426 InstanceIdentifier<IpMap> id = InstanceIdentifier.builder(
427 IntextIpMap.class).child(IpMapping.class, new IpMappingKey(segid)).child(IpMap.class, new IpMapKey(internal)).build();
431 protected InstanceIdentifier<ExternalIpCounter> getExternalIpsIdentifier(long segmentId, String external) {
432 InstanceIdentifier<ExternalIpCounter> id = InstanceIdentifier.builder(ExternalIpsCounter.class).child(ExternalCounters.class, new ExternalCountersKey(segmentId))
433 .child(ExternalIpCounter.class, new ExternalIpCounterKey(external)).build();
437 public static List<IpMap> getIpMapList(DataBroker broker, Long routerId) {
438 InstanceIdentifier<IpMapping> id = getIpMapList(routerId);
439 Optional<IpMapping> ipMappingListData = NatUtil.read(broker, LogicalDatastoreType.OPERATIONAL, id);
440 if (ipMappingListData.isPresent()) {
441 IpMapping ipMapping = ipMappingListData.get();
442 return ipMapping.getIpMap();
447 protected static InstanceIdentifier<IpMapping> getIpMapList(long routerId) {
448 InstanceIdentifier<IpMapping> id = InstanceIdentifier.builder(
449 IntextIpMap.class).child(IpMapping.class, new IpMappingKey(routerId)).build();
453 protected InstanceIdentifier<IpPortMap> getIpPortMapIdentifier(long segid, String internal, NAPTEntryEvent.Protocol protocol) {
454 ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
455 InstanceIdentifier<IpPortMap> id = InstanceIdentifier.builder(
456 IntextIpPortMap.class).child(IpPortMapping.class, new IpPortMappingKey(segid)).child(IntextIpProtocolType.class, new IntextIpProtocolTypeKey(protocolType)).
457 child(IpPortMap.class, new IpPortMapKey(internal)).build();
461 protected SessionAddress checkIpPortMap(long segmentId, String internalIpPort, NAPTEntryEvent.Protocol protocol) {
463 LOG.debug("NAPT Service : checkIpPortMap called with segmentId {} and internalIpPort {}", segmentId, internalIpPort);
464 ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
465 // check if ip-port-map node is there
466 InstanceIdentifierBuilder<IntextIpProtocolType> idBuilder =
467 InstanceIdentifier.builder(IntextIpPortMap.class).child(IpPortMapping.class, new IpPortMappingKey(segmentId)).child(IntextIpProtocolType.class, new IntextIpProtocolTypeKey(protocolType));
468 InstanceIdentifier<IntextIpProtocolType> id = idBuilder.build();
469 Optional<IntextIpProtocolType> intextIpProtocolType = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id);
470 if (intextIpProtocolType.isPresent()) {
471 List<IpPortMap> ipPortMaps = intextIpProtocolType.get().getIpPortMap();
472 for (IpPortMap ipPortMap : ipPortMaps) {
473 if (ipPortMap.getIpPortInternal().equals(internalIpPort)) {
474 LOG.debug("NAPT Service : IpPortMap : {}", ipPortMap);
475 SessionAddress externalIpPort = new SessionAddress(ipPortMap.getIpPortExternal().getIpAddress(),
476 ipPortMap.getIpPortExternal().getPortNum());
477 LOG.debug("NAPT Service : checkIpPortMap returning successfully externalIP {} and port {}",
478 externalIpPort.getIpAddress(), externalIpPort.getPortNumber());
479 return externalIpPort;
483 // return null if not found
484 LOG.error("NAPT Service : no-entry in checkIpPortMap, returning NULL [should be OK] for segmentId {} and internalIPPort {}", segmentId, internalIpPort);
488 protected String checkIpMap(long segmentId, String internalIp) {
490 LOG.debug("NAPT Service : checkIpMap called with segmentId {} and internalIp {}", segmentId, internalIp);
492 // check if ip-map node is there
493 InstanceIdentifierBuilder<IpMapping> idBuilder =
494 InstanceIdentifier.builder(IntextIpMap.class).child(IpMapping.class, new IpMappingKey(segmentId));
495 InstanceIdentifier<IpMapping> id = idBuilder.build();
496 Optional<IpMapping> ipMapping = MDSALUtil.read(broker, LogicalDatastoreType.OPERATIONAL, id);
497 if (ipMapping.isPresent()) {
498 List<IpMap> ipMaps = ipMapping.get().getIpMap();
499 for (IpMap ipMap : ipMaps) {
500 if (ipMap.getInternalIp().equals(internalIp)) {
501 LOG.debug("NAPT Service : IpMap : {}", ipMap);
502 externalIp = ipMap.getExternalIp().toString();
503 LOG.debug("NAPT Service : checkIpMap successfully returning externalIp {}", externalIp );
505 } else if (ipMap.getInternalIp().contains("/")) { // subnet case
506 SubnetUtils subnetUtils = new SubnetUtils(ipMap.getInternalIp());
507 SubnetInfo subnetInfo = subnetUtils.getInfo();
508 if (subnetInfo.isInRange(internalIp)) {
509 LOG.debug("NAPT Service : internalIp {} found to be IpMap of internalIpSubnet {}", internalIp, ipMap.getInternalIp());
510 externalIp = ipMap.getExternalIp().toString();
511 LOG.debug("NAPT Service : checkIpMap successfully returning externalIp {}", externalIp );
517 // return null if not found
518 LOG.error("NAPT Service : checkIpMap failed, returning NULL for segmentId {} and internalIp {}", segmentId, internalIp);
522 protected void removeSnatIntIpPortDS(long segmentId, SessionAddress address,NAPTEntryEvent.Protocol protocol) {
523 LOG.trace("NAPT Service : removeSnatIntIpPortDS method called for IntIpport {} of router {} ",address,segmentId);
524 ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
525 List<Integer> portList = NatUtil.getInternalIpPortListInfo(broker,segmentId,address.getIpAddress(),protocolType);
526 if (portList == null || portList.isEmpty() || !portList.contains(address.getPortNumber())) {
527 LOG.debug("Internal IP {} for port {} entry not found in SnatIntIpPort DS",address.getIpAddress(),address.getPortNumber());
530 LOG.trace("NAPT Service : PortList {} retrieved for InternalIp {} of router {}",portList,address.getIpAddress(),segmentId);
531 Integer port = address.getPortNumber();
532 portList.remove(port);
534 IntIpProtoTypeBuilder builder = new IntIpProtoTypeBuilder();
535 IntIpProtoType intIpProtocolType = builder.setKey(new IntIpProtoTypeKey(protocolType)).setPorts(portList).build();
537 MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, NatUtil.buildSnatIntIpPortIdentifier(segmentId, address.getIpAddress(), protocolType), intIpProtocolType);
538 } catch (Exception ex) {
539 LOG.error("NAPT Service : Failed to write into snat-internal-ip-port-info with exception {}", ex.getMessage() );
541 LOG.debug("NAPT Service : Removing SnatIp {} Port {} of router {} from SNATIntIpport datastore : {}"
542 ,address.getIpAddress(),address.getPortNumber(),segmentId);
545 protected void removeFromSnatIpPortDS(long segmentId, String internalIp) {
546 InstanceIdentifier<IpPort> intIp = InstanceIdentifier.builder(SnatintIpPortMap.class).child
547 (IntipPortMap.class, new IntipPortMapKey(segmentId)).child(IpPort.class, new IpPortKey(internalIp)).build();
548 // remove from SnatIpPortDS
549 LOG.debug("NAPT Service : Removing SnatIpPort from datastore : {}", intIp);
550 MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, intIp);
554 protected void removeFromIpPortMapDS(long segmentId, String internalIpPort, NAPTEntryEvent.Protocol protocol) {
555 ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
556 removeFromIpPortMapDS(segmentId, internalIpPort, protocolType);
559 protected void removeFromIpPortMapDS(long segmentId, String internalIpPort, ProtocolTypes protocolType) {
560 InstanceIdentifierBuilder<IpPortMap> idBuilder = InstanceIdentifier.builder(IntextIpPortMap.class)
561 .child(IpPortMapping.class, new IpPortMappingKey(segmentId)).child(IntextIpProtocolType.class, new IntextIpProtocolTypeKey(protocolType))
562 .child(IpPortMap.class, new IpPortMapKey(internalIpPort));
563 InstanceIdentifier<IpPortMap> id = idBuilder.build();
564 // remove from ipportmap DS
565 LOG.debug("NAPT Service : Removing ipportmap from datastore : {}", id);
566 MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, id);
569 protected void removeFromIpMapDS(long segmentId, String internalIp) {
570 InstanceIdentifierBuilder<IpMap> idBuilder = InstanceIdentifier.builder(IntextIpMap.class)
571 .child(IpMapping.class, new IpMappingKey(segmentId))
572 .child(IpMap.class, new IpMapKey(internalIp));
573 InstanceIdentifier<IpMap> id = idBuilder.build();
574 // Get externalIp and decrement the counter
575 String externalIp = null;
576 Optional<IpMap> ipMap = MDSALUtil.read(broker, LogicalDatastoreType.OPERATIONAL, id);
577 if (ipMap.isPresent()) {
578 externalIp = ipMap.get().getExternalIp();
579 LOG.debug("NAT Service : externalIP is {}", externalIp);
581 LOG.warn("NAT Service : ipMap not present for the internal IP {}", internalIp);
584 if(externalIp!=null) {
585 updateCounter(segmentId, externalIp, false);
586 // remove from ipmap DS
587 LOG.debug("NAPT Service : Removing ipmap from datastore");
588 MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, id);
590 LOG.warn("NAT Service : externalIp not present for the internal IP {}", internalIp);
594 protected void removeIntExtIpMapDS(long segmentId, String internalIp) {
595 InstanceIdentifierBuilder<IpMap> idBuilder = InstanceIdentifier.builder(IntextIpMap.class)
596 .child(IpMapping.class, new IpMappingKey(segmentId))
597 .child(IpMap.class, new IpMapKey(internalIp));
598 InstanceIdentifier<IpMap> id = idBuilder.build();
600 LOG.debug("NAPT Service : Removing ipmap from datastore");
601 MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, id);
604 protected String getExternalIpAllocatedForSubnet(long segmentId, String internalIp) {
605 InstanceIdentifierBuilder<IpMap> idBuilder = InstanceIdentifier.builder(IntextIpMap.class)
606 .child(IpMapping.class, new IpMappingKey(segmentId))
607 .child(IpMap.class, new IpMapKey(internalIp));
608 InstanceIdentifier<IpMap> id = idBuilder.build();
610 Optional<IpMap> ipMap = MDSALUtil.read(broker, LogicalDatastoreType.OPERATIONAL, id);
611 if (ipMap.isPresent()) {
612 return ipMap.get().getExternalIp();
617 private void removeIpMappingForRouterID(long segmentId) {
618 InstanceIdentifierBuilder<IpMapping> idBuilder = InstanceIdentifier.builder(IntextIpMap.class)
619 .child(IpMapping.class, new IpMappingKey(segmentId));
620 InstanceIdentifier<IpMapping> id = idBuilder.build();
621 // Get all externalIps and decrement their counters before deleting the ipmap
622 String externalIp = null;
623 Optional<IpMapping> ipMapping = MDSALUtil.read(broker, LogicalDatastoreType.OPERATIONAL, id);
624 if (ipMapping.isPresent()) {
625 List<IpMap> ipMaps = ipMapping.get().getIpMap();
626 for (IpMap ipMap : ipMaps) {
627 externalIp = ipMap.getExternalIp();
628 LOG.debug("NAT Service : externalIP is {}", externalIp);
629 if(externalIp!=null) {
630 updateCounter(segmentId, externalIp, false);
634 // remove from ipmap DS
635 LOG.debug("NAPT Service : Removing Ipmap for router {} from datastore",segmentId);
636 MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, id);
639 void removeIpPortMappingForRouterID(long segmentId) {
640 InstanceIdentifier<IpPortMapping> idBuilder = InstanceIdentifier.builder(IntextIpPortMap.class)
641 .child(IpPortMapping.class, new IpPortMappingKey(segmentId)).build();
642 // remove from IntExtIpPortmap DS
643 LOG.debug("NAPT Service : Removing IntExtIpPort map for router {} from datastore",segmentId);
644 MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, idBuilder);
647 void removeIntIpPortMappingForRouterID(long segmentId) {
648 InstanceIdentifier<IntipPortMap> intIp = InstanceIdentifier.builder(SnatintIpPortMap.class).child
649 (IntipPortMap.class, new IntipPortMapKey(segmentId)).build();
650 // remove from SnatIntIpPortmap DS
651 LOG.debug("NAPT Service : Removing SnatIntIpPort from datastore : {}", intIp);
652 MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, intIp);
655 void removePortFromPool(String internalIpPort, String externalIp) {
656 LOG.debug("NAPT Service : removePortFromPool method called");
657 ReleaseIdInput idInput = new ReleaseIdInputBuilder().
658 setPoolName(externalIp)
659 .setIdKey(internalIpPort).build();
661 Future<RpcResult<Void>> result = idManager.releaseId(idInput);
662 RpcResult<Void> rpcResult = result.get();
663 if(!rpcResult.isSuccessful()) {
664 LOG.error("NAPT Service : idmanager failed to remove port from pool {}", rpcResult.getErrors());
666 LOG.debug("NAPT Service : Removed port from pool for InternalIpPort {} with externalIp {}",internalIpPort,externalIp);
667 } catch (InterruptedException | ExecutionException e) {
668 LOG.error("NAPT Service : idmanager failed with Exception {} when removing entry in pool with key {}, ", e, internalIpPort);
672 protected void initialiseExternalCounter(Routers routers, long routerId){
673 LOG.debug("NAPT Service : Initialise External IPs counter");
674 List<String> externalIps = routers.getExternalIps();
676 //update the new counter value for this externalIp
677 for(String externalIp : externalIps) {
678 String[] IpSplit = externalIp.split("/");
679 String extIp = IpSplit[0];
680 String extPrefix = Short.toString(NatConstants.DEFAULT_PREFIX);
681 if(IpSplit.length==2) {
682 extPrefix = IpSplit[1];
684 extIp = extIp + "/" + extPrefix;
685 initialiseNewExternalIpCounter(routerId, extIp);
689 protected void initialiseNewExternalIpCounter(long routerId, String ExternalIp){
690 ExternalIpCounter externalIpCounterData = new ExternalIpCounterBuilder().setKey(new ExternalIpCounterKey(ExternalIp)).
691 setExternalIp(ExternalIp).setCounter((short) 0).build();
692 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, getExternalIpsIdentifier(routerId, ExternalIp), externalIpCounterData);
695 protected void removeExternalCounter(long routerId){
696 // Remove from external-counters model
697 InstanceIdentifier<ExternalCounters> id = InstanceIdentifier.builder(ExternalIpsCounter.class).child(ExternalCounters.class, new ExternalCountersKey(routerId)).build();
698 LOG.debug("NAPT Service : Removing ExternalCounterd from datastore");
699 MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, id);
702 protected void removeExternalIpCounter(long routerId, String externalIp){
703 // Remove from external-counters model
704 InstanceIdentifier<ExternalIpCounter> id = InstanceIdentifier.builder(ExternalIpsCounter.class).child(ExternalCounters.class,
705 new ExternalCountersKey(routerId)).child(ExternalIpCounter.class, new ExternalIpCounterKey(externalIp)).build();
706 LOG.debug("NAPT Service : Removing ExternalIpsCounter from datastore");
707 MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, id);