2 * Copyright (c) 2016 - 2018 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
8 package org.opendaylight.netvirt.natservice.internal;
10 import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
11 import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
12 import static org.opendaylight.netvirt.natservice.internal.NatUtil.requireNonNullElse;
14 import com.google.common.base.Optional;
15 import com.google.common.collect.HashBasedTable;
16 import com.google.common.collect.Table;
17 import com.google.common.util.concurrent.FluentFuture;
18 import com.google.common.util.concurrent.ListenableFuture;
19 import com.google.common.util.concurrent.MoreExecutors;
20 import java.math.BigInteger;
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.List;
24 import java.util.concurrent.Callable;
25 import java.util.concurrent.ExecutionException;
26 import java.util.concurrent.Future;
27 import java.util.concurrent.locks.ReentrantLock;
28 import javax.annotation.Nonnull;
29 import javax.annotation.Nullable;
30 import javax.inject.Inject;
31 import javax.inject.Singleton;
32 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
33 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
34 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
35 import org.opendaylight.genius.infra.Datastore.Operational;
36 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
37 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
38 import org.opendaylight.genius.infra.TypedReadWriteTransaction;
39 import org.opendaylight.genius.mdsalutil.FlowEntity;
40 import org.opendaylight.genius.mdsalutil.NwConstants;
41 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
42 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces.RouterInterface;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.NaptSwitches;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProtocolTypes;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMap;
52 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;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitch;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitchKey;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.neutron.vip.states.VipState;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPort;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoType;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortInputBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortOutput;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService;
61 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
62 import org.opendaylight.yangtools.yang.common.RpcResult;
63 import org.slf4j.Logger;
64 import org.slf4j.LoggerFactory;
67 public class NatSouthboundEventHandlers {
69 private static final Logger LOG = LoggerFactory.getLogger(NatSouthboundEventHandlers.class);
70 private static final String NAT_DS = "NATDS";
71 private final DataBroker dataBroker;
72 private final ManagedNewTransactionRunner txRunner;
73 private final OdlInterfaceRpcService odlInterfaceRpcService;
74 private final JobCoordinator coordinator;
75 private final FloatingIPListener floatingIPListener;
76 private final NeutronvpnService neutronVpnService;
77 private final IMdsalApiManager mdsalManager;
78 private final NaptManager naptManager;
79 private final VipStateTracker vipStateTracker;
80 Table<Interface.OperStatus, Interface.OperStatus, IntfTransitionState> stateTable = HashBasedTable.create();
82 enum IntfTransitionState {
88 private void initialize() {
89 stateTable.put(Interface.OperStatus.Up, Interface.OperStatus.Down, IntfTransitionState.STATE_DOWN);
90 stateTable.put(Interface.OperStatus.Down, Interface.OperStatus.Up, IntfTransitionState.STATE_UP);
91 stateTable.put(Interface.OperStatus.Unknown, Interface.OperStatus.Up, IntfTransitionState.STATE_UP);
92 stateTable.put(Interface.OperStatus.Unknown, Interface.OperStatus.Down, IntfTransitionState.STATE_DOWN);
93 stateTable.put(Interface.OperStatus.Up, Interface.OperStatus.Unknown, IntfTransitionState.STATE_DOWN);
97 public NatSouthboundEventHandlers(final DataBroker dataBroker,
98 final OdlInterfaceRpcService odlInterfaceRpcService, final JobCoordinator coordinator,
99 final FloatingIPListener floatingIPListener,final NeutronvpnService neutronvpnService,
100 final IMdsalApiManager mdsalManager, final NaptManager naptManager, final VipStateTracker vipStateTracker) {
101 this.dataBroker = dataBroker;
102 this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
103 this.odlInterfaceRpcService = odlInterfaceRpcService;
104 this.coordinator = coordinator;
105 this.floatingIPListener = floatingIPListener;
106 this.neutronVpnService = neutronvpnService;
107 this.mdsalManager = mdsalManager;
108 this.naptManager = naptManager;
109 this.vipStateTracker = vipStateTracker;
113 public void handleAdd(String interfaceName, BigInteger intfDpnId, RouterInterface routerInterface) {
114 handleAdd(interfaceName, intfDpnId, routerInterface, null);
117 public void handleAdd(String interfaceName, BigInteger intfDpnId,
118 RouterInterface routerInterface, @Nullable VipState vipState) {
119 String routerName = routerInterface.getRouterName();
120 NatInterfaceStateAddWorker natIfaceStateAddWorker = new NatInterfaceStateAddWorker(interfaceName,
121 intfDpnId, routerName);
122 coordinator.enqueueJob(NAT_DS + "-" + interfaceName, natIfaceStateAddWorker);
124 NatFlowAddWorker natFlowAddWorker = new NatFlowAddWorker(interfaceName, routerName, intfDpnId, vipState);
125 coordinator.enqueueJob(NAT_DS + "-" + interfaceName, natFlowAddWorker, NatConstants.NAT_DJC_MAX_RETRIES);
128 public void handleRemove(String interfaceName, BigInteger intfDpnId, RouterInterface routerInterface) {
129 String routerName = routerInterface.getRouterName();
130 NatInterfaceStateRemoveWorker natIfaceStateRemoveWorker = new NatInterfaceStateRemoveWorker(interfaceName,
131 intfDpnId, routerName);
132 coordinator.enqueueJob(NAT_DS + "-" + interfaceName, natIfaceStateRemoveWorker);
134 NatFlowRemoveWorker natFlowRemoveWorker = new NatFlowRemoveWorker(interfaceName, intfDpnId, routerName);
135 coordinator.enqueueJob(NAT_DS + "-" + interfaceName, natFlowRemoveWorker,
136 NatConstants.NAT_DJC_MAX_RETRIES);
139 public void handleUpdate(Interface original, Interface update,
140 BigInteger intfDpnId, RouterInterface routerInterface) {
141 String routerName = routerInterface.getRouterName();
142 NatInterfaceStateUpdateWorker natIfaceStateupdateWorker = new NatInterfaceStateUpdateWorker(original,
143 update, intfDpnId, routerName);
144 coordinator.enqueueJob(NAT_DS + "-" + update.getName(), natIfaceStateupdateWorker);
145 NatFlowUpdateWorker natFlowUpdateWorker = new NatFlowUpdateWorker(original, update, routerName);
146 coordinator.enqueueJob(NAT_DS + "-" + update.getName(), natFlowUpdateWorker,
147 NatConstants.NAT_DJC_MAX_RETRIES);
150 void handleRouterInterfacesUpEvent(String routerName, String interfaceName, BigInteger dpId,
151 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
152 LOG.debug("handleRouterInterfacesUpEvent : Handling UP event for router interface {} in Router {} on Dpn {}",
153 interfaceName, routerName, dpId);
154 NatUtil.addToNeutronRouterDpnsMap(routerName, interfaceName, dpId, operTx);
155 NatUtil.addToDpnRoutersMap(routerName, interfaceName, dpId, operTx);
158 void handleRouterInterfacesDownEvent(String routerName, String interfaceName, BigInteger dpnId,
159 TypedReadWriteTransaction<Operational> operTx)
160 throws ExecutionException, InterruptedException {
161 LOG.debug("handleRouterInterfacesDownEvent : Handling DOWN event for router Interface {} in Router {}",
162 interfaceName, routerName);
163 NatUtil.removeFromNeutronRouterDpnsMap(routerName, dpnId, operTx);
164 NatUtil.removeFromDpnRoutersMap(dataBroker, routerName, interfaceName, dpnId, odlInterfaceRpcService,
168 private IntfTransitionState getTransitionState(Interface.OperStatus original , Interface.OperStatus updated) {
169 IntfTransitionState transitionState = stateTable.get(original, updated);
171 if (transitionState == null) {
172 return IntfTransitionState.STATE_IGNORE;
174 return transitionState;
177 private class NatInterfaceStateAddWorker implements Callable<List<ListenableFuture<Void>>> {
178 private final String interfaceName;
179 private final String routerName;
180 private final BigInteger intfDpnId;
182 NatInterfaceStateAddWorker(String interfaceName, BigInteger intfDpnId, String routerName) {
183 this.interfaceName = interfaceName;
184 this.routerName = routerName;
185 this.intfDpnId = intfDpnId;
189 @SuppressWarnings("checkstyle:IllegalCatch")
190 public List<ListenableFuture<Void>> call() {
191 LOG.trace("call : Received interface {} PORT UP OR ADD event ", interfaceName);
192 List<ListenableFuture<Void>> futures = new ArrayList<>();
193 final ReentrantLock lock = NatUtil.lockForNat(intfDpnId);
196 futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, tx ->
197 handleRouterInterfacesUpEvent(routerName, interfaceName, intfDpnId, tx)));
198 } catch (Exception e) {
199 LOG.error("call : Exception caught in Interface {} Operational State Up event",
208 private class NatInterfaceStateRemoveWorker implements Callable<List<ListenableFuture<Void>>> {
209 private final String interfaceName;
210 private final String routerName;
211 private final BigInteger intfDpnId;
213 NatInterfaceStateRemoveWorker(String interfaceName, BigInteger intfDpnId, String routerName) {
214 this.interfaceName = interfaceName;
215 this.routerName = routerName;
216 this.intfDpnId = intfDpnId;
220 @SuppressWarnings("checkstyle:IllegalCatch")
221 public List<ListenableFuture<Void>> call() {
222 LOG.trace("call : Received interface {} PORT DOWN or REMOVE event", interfaceName);
223 List<ListenableFuture<Void>> futures = new ArrayList<>();
224 final ReentrantLock lock = NatUtil.lockForNat(intfDpnId);
227 futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, tx ->
228 handleRouterInterfacesDownEvent(routerName, interfaceName, intfDpnId, tx)));
229 } catch (Exception e) {
230 LOG.error("call : Exception observed in handling deletion of VPN Interface {}.", interfaceName, e);
238 private class NatInterfaceStateUpdateWorker implements Callable<List<ListenableFuture<Void>>> {
239 private final Interface original;
240 private final Interface update;
241 private final BigInteger intfDpnId;
242 private final String routerName;
244 NatInterfaceStateUpdateWorker(Interface original, Interface update, BigInteger intfDpnId, String routerName) {
245 this.original = original;
246 this.update = update;
247 this.intfDpnId = intfDpnId;
248 this.routerName = routerName;
252 @SuppressWarnings("checkstyle:IllegalCatch")
253 public List<ListenableFuture<Void>> call() {
254 final String interfaceName = update.getName();
255 LOG.trace("call : Received interface {} state change event", interfaceName);
256 LOG.debug("call : DPN ID {} for the interface {} ", intfDpnId, interfaceName);
258 List<ListenableFuture<Void>> futures = new ArrayList<>();
259 final ReentrantLock lock = NatUtil.lockForNat(intfDpnId);
262 IntfTransitionState state = getTransitionState(original.getOperStatus(), update.getOperStatus());
263 if (state.equals(IntfTransitionState.STATE_IGNORE)) {
264 LOG.info("NAT Service: Interface {} state original {} updated {} not handled",
265 interfaceName, original.getOperStatus(), update.getOperStatus());
268 futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, tx -> {
269 if (state.equals(IntfTransitionState.STATE_DOWN)) {
270 LOG.debug("call : DPN {} connnected to the interface {} has gone down."
271 + "Hence clearing the dpn-vpninterfaces-list entry from the"
272 + " neutron-router-dpns model in the ODL:L3VPN", intfDpnId, interfaceName);
273 // If the interface state is unknown, it means that the corresponding DPN has gone down.
274 // So remove the dpn-vpninterfaces-list from the neutron-router-dpns model.
275 NatUtil.removeFromNeutronRouterDpnsMap(routerName, interfaceName,
277 } else if (state.equals(IntfTransitionState.STATE_UP)) {
278 LOG.debug("call : DPN {} connnected to the interface {} has come up. Hence adding"
279 + " the dpn-vpninterfaces-list entry from the neutron-router-dpns model"
280 + " in the ODL:L3VPN", intfDpnId, interfaceName);
281 handleRouterInterfacesUpEvent(routerName, interfaceName, intfDpnId, tx);
284 } catch (Exception e) {
285 LOG.error("call : Exception observed in handling updation of VPN Interface {}.", update.getName(), e);
293 private void processInterfaceAdded(String portName, String routerId, BigInteger dpnId, VipState vipState) {
294 LOG.trace("processInterfaceAdded : Processing Interface Add Event for interface {}", portName);
295 List<InternalToExternalPortMap> intExtPortMapList = getIntExtPortMapListForPortName(portName, routerId);
296 if (intExtPortMapList.isEmpty()) {
297 LOG.debug("processInterfaceAdded : Ip Mapping list is empty/null for portname {}", portName);
300 InstanceIdentifier<RouterPorts> portIid = NatUtil.buildRouterPortsIdentifier(routerId);
301 FluentFuture<Void> future = txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
302 for (InternalToExternalPortMap intExtPortMap : intExtPortMapList) {
303 floatingIPListener.createNATFlowEntries(portName, intExtPortMap, portIid, routerId, dpnId, tx);
306 future.transform((ignored) -> {
307 if (vipState != null) {
308 return this.vipStateTracker.writeVipState(vipState);
311 }, MoreExecutors.directExecutor());
315 private List<InternalToExternalPortMap> getIntExtPortMapListForPortName(String portName, String routerId) {
316 InstanceIdentifier<Ports> portToIpMapIdentifier = NatUtil.buildPortToIpMapIdentifier(routerId, portName);
317 Optional<Ports> port =
318 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
319 LogicalDatastoreType.CONFIGURATION, portToIpMapIdentifier);
320 if (!port.isPresent()) {
321 LOG.info("getIntExtPortMapListForPortName : Unable to read router port entry for router ID {} "
322 + "and port name {}", routerId, portName);
323 return Collections.emptyList();
325 return requireNonNullElse(port.get().getInternalToExternalPortMap(), Collections.emptyList());
329 private BigInteger getNaptSwitchforRouter(DataBroker broker, String routerName) {
330 InstanceIdentifier<RouterToNaptSwitch> rtrNaptSw = InstanceIdentifier.builder(NaptSwitches.class)
331 .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerName)).build();
332 Optional<RouterToNaptSwitch> routerToNaptSwitchData =
333 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
334 LogicalDatastoreType.CONFIGURATION, rtrNaptSw);
335 if (routerToNaptSwitchData.isPresent()) {
336 RouterToNaptSwitch routerToNaptSwitchInstance = routerToNaptSwitchData.get();
337 return routerToNaptSwitchInstance.getPrimarySwitchId();
342 private void removeNatFlow(BigInteger dpnId, short tableId, Long routerId, String ipAddress, int ipPort) {
344 String switchFlowRef = NatUtil.getNaptFlowRef(dpnId, tableId, String.valueOf(routerId), ipAddress, ipPort);
345 FlowEntity snatFlowEntity = NatUtil.buildFlowEntity(dpnId, tableId, switchFlowRef);
347 mdsalManager.removeFlow(snatFlowEntity);
348 LOG.debug("removeNatFlow : Removed the flow in table {} for the switch with the DPN ID {} for "
349 + "router {} ip {} port {}", tableId, dpnId, routerId, ipAddress, ipPort);
353 private List<String> getFixedIpsForPort(String interfname) {
354 LOG.debug("getFixedIpsForPort : getFixedIpsForPort method is called for interface {}", interfname);
356 Future<RpcResult<GetFixedIPsForNeutronPortOutput>> result =
357 neutronVpnService.getFixedIPsForNeutronPort(new GetFixedIPsForNeutronPortInputBuilder()
358 .setPortId(new Uuid(interfname)).build());
360 RpcResult<GetFixedIPsForNeutronPortOutput> rpcResult = result.get();
361 if (!rpcResult.isSuccessful()) {
362 LOG.error("getFixedIpsForPort : RPC Call to GetFixedIPsForNeutronPortOutput returned with Errors {}",
363 rpcResult.getErrors());
365 return rpcResult.getResult().getFixedIPs();
367 } catch (InterruptedException | ExecutionException | NullPointerException ex) {
368 LOG.error("getFixedIpsForPort : Exception while receiving fixedIps for port {}", interfname, ex);
373 private void processInterfaceRemoved(String portName, BigInteger dpnId, String routerId,
374 List<ListenableFuture<Void>> futures) {
375 LOG.trace("processInterfaceRemoved : Processing Interface Removed Event for interface {} on DPN ID {}",
377 List<InternalToExternalPortMap> intExtPortMapList = getIntExtPortMapListForPortName(portName, routerId);
378 if (intExtPortMapList.isEmpty()) {
379 LOG.debug("processInterfaceRemoved : Ip Mapping list is empty/null for portName {}", portName);
382 InstanceIdentifier<RouterPorts> portIid = NatUtil.buildRouterPortsIdentifier(routerId);
383 ListenableFuture<Void> future = txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
384 for (InternalToExternalPortMap intExtPortMap : intExtPortMapList) {
385 LOG.trace("processInterfaceRemoved : Removing DNAT Flow entries for dpnId {} ", dpnId);
386 floatingIPListener.removeNATFlowEntries(portName, intExtPortMap, portIid, routerId, dpnId, tx);
392 } catch (InterruptedException | ExecutionException e) {
393 LOG.error("Error processing interface removal", e);
397 // TODO Clean up the exception handling
398 @SuppressWarnings("checkstyle:IllegalCatch")
399 private void removeSnatEntriesForPort(String interfaceName, String routerName) {
400 Long routerId = NatUtil.getVpnId(dataBroker, routerName);
401 if (routerId == NatConstants.INVALID_ID) {
402 LOG.error("removeSnatEntriesForPort : routerId not found for routername {}", routerName);
405 BigInteger naptSwitch = getNaptSwitchforRouter(dataBroker, routerName);
406 if (naptSwitch == null || naptSwitch.equals(BigInteger.ZERO)) {
407 LOG.error("removeSnatEntriesForPort : NaptSwitch is not elected for router {} with Id {}",
408 routerName, routerId);
411 //getInternalIp for port
412 List<String> fixedIps = getFixedIpsForPort(interfaceName);
413 if (fixedIps == null) {
414 LOG.warn("removeSnatEntriesForPort : Internal Ips not found for InterfaceName {} in router {} with id {}",
415 interfaceName, routerName, routerId);
419 for (String internalIp : fixedIps) {
420 LOG.debug("removeSnatEntriesForPort : Internal Ip retrieved for interface {} is {} in router with Id {}",
421 interfaceName, internalIp, routerId);
422 IpPort ipPort = NatUtil.getInternalIpPortInfo(dataBroker, routerId, internalIp);
423 if (ipPort == null) {
424 LOG.debug("removeSnatEntriesForPort : no snatint-ip-port-map found for ip:{}", internalIp);
428 for (IntIpProtoType protoType : requireNonNullElse(ipPort.getIntIpProtoType(),
429 Collections.<IntIpProtoType>emptyList())) {
430 ProtocolTypes protocol = protoType.getProtocol();
431 for (Integer portnum : requireNonNullElse(protoType.getPorts(), Collections.<Integer>emptyList())) {
432 //build and remove the flow in outbound table
434 removeNatFlow(naptSwitch, NwConstants.OUTBOUND_NAPT_TABLE, routerId, internalIp, portnum);
435 } catch (Exception ex) {
436 LOG.error("removeSnatEntriesForPort : Failed to remove snat flow for internalIP {} with "
437 + "Port {} protocol {} for routerId {} in OUTBOUNDTABLE of NaptSwitch {}",
438 internalIp, portnum, protocol, routerId, naptSwitch, ex);
440 //Get the external IP address and the port from the model
441 NAPTEntryEvent.Protocol proto = protocol.toString().equals(ProtocolTypes.TCP.toString())
442 ? NAPTEntryEvent.Protocol.TCP : NAPTEntryEvent.Protocol.UDP;
443 IpPortExternal ipPortExternal = NatUtil.getExternalIpPortMap(dataBroker, routerId,
444 internalIp, String.valueOf(portnum), proto);
445 if (ipPortExternal == null) {
446 LOG.error("removeSnatEntriesForPort : Mapping for internalIp {} with port {} is not found in "
447 + "router with Id {}", internalIp, portnum, routerId);
450 String externalIpAddress = ipPortExternal.getIpAddress();
451 Integer portNumber = ipPortExternal.getPortNum();
453 //build and remove the flow in inboundtable
455 removeNatFlow(naptSwitch, NwConstants.INBOUND_NAPT_TABLE, routerId,
456 externalIpAddress, portNumber);
457 } catch (Exception ex) {
458 LOG.error("removeSnatEntriesForPort : Failed to remove snat flow internalIP {} with "
459 + "Port {} protocol {} for routerId {} in INBOUNDTABLE of naptSwitch {}",
460 externalIpAddress, portNumber, protocol, routerId, naptSwitch, ex);
463 String internalIpPort = internalIp + ":" + portnum;
464 // delete the entry from IntExtIpPortMap DS
466 naptManager.removeFromIpPortMapDS(routerId, internalIpPort, proto);
467 naptManager.removePortFromPool(internalIpPort, externalIpAddress);
468 } catch (Exception ex) {
469 LOG.error("removeSnatEntriesForPort : releaseIpExtPortMapping failed, Removal of "
470 + "ipportmap {} for router {} failed", internalIpPort, routerId, ex);
474 // delete the entry from SnatIntIpPortMap DS
475 LOG.debug("removeSnatEntriesForPort : Removing InternalIp:{} on router {}", internalIp, routerId);
476 naptManager.removeFromSnatIpPortDS(routerId, internalIp);
480 private class NatFlowAddWorker implements Callable<List<ListenableFuture<Void>>> {
481 private final String interfaceName;
482 private final String routerName;
483 private final BigInteger dpnId;
484 private final VipState vipState;
486 NatFlowAddWorker(String interfaceName,String routerName, BigInteger dpnId, VipState vipState) {
487 this.interfaceName = interfaceName;
488 this.routerName = routerName;
490 this.vipState = vipState;
494 @SuppressWarnings("checkstyle:IllegalCatch")
495 public List<ListenableFuture<Void>> call() {
496 final List<ListenableFuture<Void>> futures = new ArrayList<>();
497 LOG.trace("call : Interface {} up event received", interfaceName);
499 LOG.trace("call : Port added event received for interface {} ", interfaceName);
500 processInterfaceAdded(interfaceName, routerName, dpnId, vipState);
501 } catch (Exception ex) {
502 LOG.error("call : Exception caught in Interface {} Operational State Up event",
509 private class NatFlowUpdateWorker implements Callable<List<ListenableFuture<Void>>> {
510 private final Interface original;
511 private final Interface update;
512 private final String routerName;
514 NatFlowUpdateWorker(Interface original, Interface update, String routerName) {
515 this.original = original;
516 this.update = update;
517 this.routerName = routerName;
521 @SuppressWarnings("checkstyle:IllegalCatch")
522 public List<ListenableFuture<Void>> call() {
523 final List<ListenableFuture<Void>> futures = new ArrayList<>();
524 String interfaceName = update.getName();
525 IntfTransitionState state = getTransitionState(original.getOperStatus(), update.getOperStatus());
526 if (state.equals(IntfTransitionState.STATE_IGNORE)) {
527 LOG.info("NAT Service: Interface {} state original {} updated {} not handled",
528 interfaceName, original.getOperStatus(), update.getOperStatus());
531 if (state.equals(IntfTransitionState.STATE_UP)) {
532 LOG.debug("call : Port UP event received for interface {} ", interfaceName);
533 } else if (state.equals(IntfTransitionState.STATE_DOWN)) {
534 LOG.debug("call : Port DOWN event received for interface {} ", interfaceName);
536 removeSnatEntriesForPort(interfaceName, routerName);
537 } catch (Exception ex) {
538 LOG.error("call : Exception caught in Interface {} OperationalStateDown", interfaceName, ex);
545 private class NatFlowRemoveWorker implements Callable<List<ListenableFuture<Void>>> {
546 private final String interfaceName;
547 private final String routerName;
548 private final BigInteger intfDpnId;
550 NatFlowRemoveWorker(String interfaceName, BigInteger intfDpnId, String routerName) {
551 this.interfaceName = interfaceName;
552 this.routerName = routerName;
553 this.intfDpnId = intfDpnId;
557 @SuppressWarnings("checkstyle:IllegalCatch")
558 public List<ListenableFuture<Void>> call() {
559 final List<ListenableFuture<Void>> futures = new ArrayList<>();
560 LOG.trace("call : Interface {} removed event received", interfaceName);
562 LOG.trace("call : Port removed event received for interface {} ", interfaceName);
563 processInterfaceRemoved(interfaceName, intfDpnId, routerName, futures);
564 removeSnatEntriesForPort(interfaceName, routerName);
565 } catch (Exception e) {
566 LOG.error("call : Exception caught in Interface {} OperationalStateRemove", interfaceName, e);