2 * Copyright © 2016, 2017 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;
12 import java.math.BigInteger;
13 import java.net.InetAddress;
14 import java.net.UnknownHostException;
15 import java.util.ArrayList;
16 import java.util.Collections;
17 import java.util.List;
18 import java.util.Optional;
19 import java.util.concurrent.ExecutionException;
20 import javax.annotation.PreDestroy;
21 import javax.inject.Inject;
22 import javax.inject.Singleton;
23 import org.eclipse.jdt.annotation.Nullable;
24 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
25 import org.opendaylight.genius.infra.Datastore.Configuration;
26 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
27 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
28 import org.opendaylight.genius.infra.TypedReadWriteTransaction;
29 import org.opendaylight.genius.mdsalutil.ActionInfo;
30 import org.opendaylight.genius.mdsalutil.FlowEntity;
31 import org.opendaylight.genius.mdsalutil.InstructionInfo;
32 import org.opendaylight.genius.mdsalutil.MDSALUtil;
33 import org.opendaylight.genius.mdsalutil.MatchInfo;
34 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
35 import org.opendaylight.genius.mdsalutil.NwConstants;
36 import org.opendaylight.genius.mdsalutil.actions.ActionNxLoadInPort;
37 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
38 import org.opendaylight.genius.mdsalutil.actions.ActionSetDestinationIp;
39 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldEthernetSource;
40 import org.opendaylight.genius.mdsalutil.actions.ActionSetSourceIp;
41 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
42 import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
43 import org.opendaylight.genius.mdsalutil.instructions.InstructionWriteMetadata;
44 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
45 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetDestination;
46 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
47 import org.opendaylight.genius.mdsalutil.matches.MatchIpv4Destination;
48 import org.opendaylight.genius.mdsalutil.matches.MatchIpv4Source;
49 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
50 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
51 import org.opendaylight.infrautils.utils.concurrent.Executors;
52 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
53 import org.opendaylight.mdsal.binding.api.DataBroker;
54 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
55 import org.opendaylight.netvirt.natservice.api.CentralizedSwitchScheduler;
56 import org.opendaylight.netvirt.natservice.api.NatSwitchCache;
57 import org.opendaylight.serviceutils.tools.listener.AbstractAsyncDataTreeChangeListener;
58 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
59 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsKey;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMap;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMapBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMapKey;
74 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
75 import org.opendaylight.yangtools.yang.common.Uint32;
76 import org.opendaylight.yangtools.yang.common.Uint64;
77 import org.slf4j.Logger;
78 import org.slf4j.LoggerFactory;
81 public class FloatingIPListener extends AbstractAsyncDataTreeChangeListener<InternalToExternalPortMap> {
82 private static final Logger LOG = LoggerFactory.getLogger(FloatingIPListener.class);
83 private final DataBroker dataBroker;
84 private final ManagedNewTransactionRunner txRunner;
85 private final IMdsalApiManager mdsalManager;
86 private final OdlInterfaceRpcService interfaceManager;
87 private final FloatingIPHandler floatingIPHandler;
88 private final SNATDefaultRouteProgrammer defaultRouteProgrammer;
89 private final JobCoordinator coordinator;
90 private final CentralizedSwitchScheduler centralizedSwitchScheduler;
91 private final NatSwitchCache natSwitchCache;
94 public FloatingIPListener(final DataBroker dataBroker, final IMdsalApiManager mdsalManager,
95 final OdlInterfaceRpcService interfaceManager,
96 final FloatingIPHandler floatingIPHandler,
97 final SNATDefaultRouteProgrammer snatDefaultRouteProgrammer,
98 final JobCoordinator coordinator,
99 final CentralizedSwitchScheduler centralizedSwitchScheduler,
100 final NatSwitchCache natSwitchCache) {
101 super(dataBroker, LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(FloatingIpInfo.class)
102 .child(RouterPorts.class).child(Ports.class).child(InternalToExternalPortMap.class),
103 Executors.newListeningSingleThreadExecutor("FloatingIPListener", LOG));
104 this.dataBroker = dataBroker;
105 this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
106 this.mdsalManager = mdsalManager;
107 this.interfaceManager = interfaceManager;
108 this.floatingIPHandler = floatingIPHandler;
109 this.defaultRouteProgrammer = snatDefaultRouteProgrammer;
110 this.coordinator = coordinator;
111 this.centralizedSwitchScheduler = centralizedSwitchScheduler;
112 this.natSwitchCache = natSwitchCache;
116 LOG.info("{} init", getClass().getSimpleName());
121 public void close() {
123 Executors.shutdownAndAwaitTermination(getExecutorService());
127 public void add(final InstanceIdentifier<InternalToExternalPortMap> identifier,
128 final InternalToExternalPortMap mapping) {
129 LOG.trace("FloatingIPListener add ip mapping method - key: {} value: {}",mapping.key(), mapping);
130 processFloatingIPAdd(identifier, mapping);
134 public void remove(InstanceIdentifier<InternalToExternalPortMap> identifier, InternalToExternalPortMap mapping) {
135 LOG.trace("FloatingIPListener remove ip mapping method - kkey: {} value: {}",mapping.key(), mapping);
136 processFloatingIPDel(identifier, mapping);
140 public void update(InstanceIdentifier<InternalToExternalPortMap> identifier, InternalToExternalPortMap
141 original, InternalToExternalPortMap update) {
142 LOG.trace("FloatingIPListener update ip mapping method - key: {}, original: {}, update: {}",
143 update.key(), original, update);
147 private FlowEntity buildPreDNATFlowEntity(Uint64 dpId, InternalToExternalPortMap mapping, Uint32 routerId,
148 Uint32 associatedVpn) {
149 String externalIp = mapping.getExternalIp();
150 Uuid floatingIpId = mapping.getExternalId();
151 //Get the FIP MAC address for DNAT
152 String floatingIpPortMacAddress = NatUtil.getFloatingIpPortMacFromFloatingIpId(dataBroker, floatingIpId);
153 if (floatingIpPortMacAddress == null) {
154 LOG.error("buildPreDNATFlowEntity : Unable to retrieve floatingIpPortMacAddress from floating IP UUID {} "
155 + "for floating IP {}", floatingIpId, externalIp);
158 LOG.debug("buildPreDNATFlowEntity : Bulding DNAT Flow entity for ip {} ", externalIp);
159 Uint32 segmentId = associatedVpn == NatConstants.INVALID_ID ? routerId : associatedVpn;
160 LOG.debug("buildPreDNATFlowEntity : Segment id {} in build preDNAT Flow", segmentId);
162 List<MatchInfo> matches = new ArrayList<>();
163 matches.add(MatchEthernetType.IPV4);
165 matches.add(new MatchIpv4Destination(externalIp, "32"));
166 //Match Destination Floating IP MAC Address on table = 25 (PDNAT_TABLE)
167 matches.add(new MatchEthernetDestination(new MacAddress(floatingIpPortMacAddress)));
169 // matches.add(new MatchMetadata(
170 // BigInteger.valueOf(vpnId), MetaDataUtil.METADATA_MASK_VRFID));
171 List<ActionInfo> actionsInfos = new ArrayList<>();
172 String internalIp = mapping.getInternalIp();
173 actionsInfos.add(new ActionSetDestinationIp(internalIp, "32"));
175 List<InstructionInfo> instructions = new ArrayList<>();
176 instructions.add(new InstructionWriteMetadata(MetaDataUtil.getVpnIdMetadata(segmentId.longValue()),
177 MetaDataUtil.METADATA_MASK_VRFID));
178 instructions.add(new InstructionApplyActions(actionsInfos));
179 instructions.add(new InstructionGotoTable(NwConstants.DNAT_TABLE));
181 String flowRef = NatUtil.getFlowRef(dpId, NwConstants.PDNAT_TABLE, routerId, externalIp);
183 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.PDNAT_TABLE, flowRef,
184 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
185 NwConstants.COOKIE_DNAT_TABLE, matches, instructions);
190 private FlowEntity buildDNATFlowEntity(Uint64 dpId, InternalToExternalPortMap mapping, Uint32 routerId, Uint32
192 String externalIp = mapping.getExternalIp();
193 LOG.info("buildDNATFlowEntity : Bulding DNAT Flow entity for ip {} ", externalIp);
195 Uint32 segmentId = associatedVpn == NatConstants.INVALID_ID ? routerId : associatedVpn;
196 LOG.debug("buildDNATFlowEntity : Segment id {} in build DNAT", segmentId);
198 List<MatchInfo> matches = new ArrayList<>();
199 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(segmentId.longValue()),
200 MetaDataUtil.METADATA_MASK_VRFID));
202 matches.add(MatchEthernetType.IPV4);
203 String internalIp = mapping.getInternalIp();
204 matches.add(new MatchIpv4Destination(internalIp, "32"));
206 List<ActionInfo> actionsInfos = new ArrayList<>();
207 // actionsInfos.add(new ActionSetDestinationIp(internalIp, "32"));
209 List<InstructionInfo> instructions = new ArrayList<>();
210 // instructions.add(new InstructionWriteMetadata(Uint64.valueOf
211 // (routerId), MetaDataUtil.METADATA_MASK_VRFID));
212 actionsInfos.add(new ActionNxLoadInPort(Uint64.valueOf(BigInteger.ZERO)));
213 actionsInfos.add(new ActionNxResubmit(NwConstants.L3_FIB_TABLE));
214 instructions.add(new InstructionApplyActions(actionsInfos));
215 //instructions.add(new InstructionGotoTable(NatConstants.L3_FIB_TABLE));
217 String flowRef = NatUtil.getFlowRef(dpId, NwConstants.DNAT_TABLE, routerId, internalIp);
219 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.DNAT_TABLE, flowRef,
220 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
221 NwConstants.COOKIE_DNAT_TABLE, matches, instructions);
227 private FlowEntity buildPreSNATFlowEntity(Uint64 dpId, String internalIp, String externalIp, Uint32 vpnId, Uint32
228 routerId, Uint32 associatedVpn) {
230 LOG.debug("buildPreSNATFlowEntity : Building PSNAT Flow entity for ip {} ", internalIp);
232 Uint32 segmentId = associatedVpn == NatConstants.INVALID_ID ? routerId : associatedVpn;
234 LOG.debug("buildPreSNATFlowEntity : Segment id {} in build preSNAT flow", segmentId);
236 List<MatchInfo> matches = new ArrayList<>();
237 matches.add(MatchEthernetType.IPV4);
239 matches.add(new MatchIpv4Source(internalIp, "32"));
241 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(segmentId.longValue()),
242 MetaDataUtil.METADATA_MASK_VRFID));
244 List<ActionInfo> actionsInfos = new ArrayList<>();
245 actionsInfos.add(new ActionSetSourceIp(externalIp, "32"));
247 List<InstructionInfo> instructions = new ArrayList<>();
249 new InstructionWriteMetadata(MetaDataUtil.getVpnIdMetadata(vpnId.longValue()),
250 MetaDataUtil.METADATA_MASK_VRFID));
251 instructions.add(new InstructionApplyActions(actionsInfos));
252 instructions.add(new InstructionGotoTable(NwConstants.SNAT_TABLE));
254 String flowRef = NatUtil.getFlowRef(dpId, NwConstants.PSNAT_TABLE, routerId, internalIp);
256 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.PSNAT_TABLE, flowRef,
257 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
258 NwConstants.COOKIE_DNAT_TABLE, matches, instructions);
264 private FlowEntity buildSNATFlowEntity(Uint64 dpId, InternalToExternalPortMap mapping, Uint32 vpnId, Uuid
266 String internalIp = mapping.getInternalIp();
267 LOG.debug("buildSNATFlowEntity : Building SNAT Flow entity for ip {} ", internalIp);
269 ProviderTypes provType = NatUtil.getProviderTypefromNetworkId(dataBroker, externalNetworkId);
270 if (provType == null) {
271 LOG.error("buildSNATFlowEntity : Unable to get Network Provider Type for network {}", externalNetworkId);
275 List<MatchInfo> matches = new ArrayList<>();
276 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId.longValue()),
277 MetaDataUtil.METADATA_MASK_VRFID));
278 matches.add(MatchEthernetType.IPV4);
279 String externalIp = mapping.getExternalIp();
280 matches.add(new MatchIpv4Source(externalIp, "32"));
282 List<ActionInfo> actionsInfo = new ArrayList<>();
283 actionsInfo.add(new ActionNxLoadInPort(Uint64.valueOf(BigInteger.ZERO)));
284 Uuid floatingIpId = mapping.getExternalId();
285 String macAddress = NatUtil.getFloatingIpPortMacFromFloatingIpId(dataBroker, floatingIpId);
286 if (macAddress != null) {
287 actionsInfo.add(new ActionSetFieldEthernetSource(new MacAddress(macAddress)));
289 LOG.warn("buildSNATFlowEntity : No MAC address found for floating IP {}", externalIp);
292 LOG.trace("buildSNATFlowEntity : External Network Provider Type is {}, resubmit to FIB", provType.toString());
293 actionsInfo.add(new ActionNxResubmit(NwConstants.L3_FIB_TABLE));
294 List<InstructionInfo> instructions = new ArrayList<>();
295 instructions.add(new InstructionApplyActions(actionsInfo));
296 String flowRef = NatUtil.getFlowRef(dpId, NwConstants.SNAT_TABLE, vpnId, externalIp);
298 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.SNAT_TABLE, flowRef,
299 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
300 NwConstants.COOKIE_DNAT_TABLE, matches, instructions);
306 private void createDNATTblEntry(Uint64 dpnId, InternalToExternalPortMap mapping, Uint32 routerId,
307 Uint32 associatedVpnId, TypedReadWriteTransaction<Configuration> confTx) {
308 FlowEntity preFlowEntity = buildPreDNATFlowEntity(dpnId, mapping, routerId, associatedVpnId);
309 if (preFlowEntity == null) {
310 LOG.error("createDNATTblEntry : Flow entity received as NULL. "
311 + "Cannot proceed with installation of Pre-DNAT flow table {} --> table {} on DpnId {}",
312 NwConstants.PDNAT_TABLE, NwConstants.DNAT_TABLE, dpnId);
314 mdsalManager.addFlow(confTx, preFlowEntity);
315 FlowEntity flowEntity = buildDNATFlowEntity(dpnId, mapping, routerId, associatedVpnId);
316 if (flowEntity != null) {
317 mdsalManager.addFlow(confTx, flowEntity);
322 private void removeDNATTblEntry(Uint64 dpnId, String internalIp, String externalIp, Uint32 routerId,
323 TypedReadWriteTransaction<Configuration> confTx) throws ExecutionException, InterruptedException {
324 FlowEntity preFlowEntity = buildPreDNATDeleteFlowEntity(dpnId, externalIp, routerId);
325 mdsalManager.removeFlow(confTx, preFlowEntity);
327 FlowEntity flowEntity = buildDNATDeleteFlowEntity(dpnId, internalIp, routerId);
328 if (flowEntity != null) {
329 mdsalManager.removeFlow(confTx, flowEntity);
333 private void createSNATTblEntry(Uint64 dpnId, InternalToExternalPortMap mapping, Uint32 vpnId, Uint32 routerId,
334 Uint32 associatedVpnId, Uuid externalNetworkId,
335 TypedReadWriteTransaction<Configuration> confTx) {
336 FlowEntity preFlowEntity = buildPreSNATFlowEntity(dpnId, mapping.getInternalIp(), mapping.getExternalIp(),
337 vpnId, routerId, associatedVpnId);
338 mdsalManager.addFlow(confTx, preFlowEntity);
340 FlowEntity flowEntity = buildSNATFlowEntity(dpnId, mapping, vpnId, externalNetworkId);
341 if (flowEntity != null) {
342 mdsalManager.addFlow(confTx, flowEntity);
346 private void removeSNATTblEntry(Uint64 dpnId, String internalIp, String externalIp, Uint32 routerId, Uint32 vpnId,
347 TypedReadWriteTransaction<Configuration> removeFlowInvTx)
348 throws ExecutionException, InterruptedException {
349 FlowEntity preFlowEntity = buildPreSNATDeleteFlowEntity(dpnId, internalIp, routerId);
350 mdsalManager.removeFlow(removeFlowInvTx, preFlowEntity);
352 FlowEntity flowEntity = buildSNATDeleteFlowEntity(dpnId, externalIp, vpnId);
353 if (flowEntity != null) {
354 mdsalManager.removeFlow(removeFlowInvTx, flowEntity);
359 private Uuid getExtNetworkId(final InstanceIdentifier<RouterPorts> portIid,
360 LogicalDatastoreType dataStoreType) {
361 Optional<RouterPorts> rtrPort =
362 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
363 dataStoreType, portIid);
364 if (!rtrPort.isPresent()) {
365 LOG.error("getExtNetworkId : Unable to read router port entry for {}", portIid);
369 return rtrPort.get().getExternalNetworkId();
372 private Uuid getVpnUuid(Uuid extNwId, Uuid floatingIpExternalId) {
374 InstanceIdentifier<Networks> nwId = InstanceIdentifier.builder(ExternalNetworks.class).child(Networks.class,
375 new NetworksKey(extNwId)).build();
376 Optional<Networks> nw =
377 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
378 LogicalDatastoreType.CONFIGURATION, nwId);
379 if (!nw.isPresent()) {
380 LOG.error("getVpnId : Unable to read external network for {}", extNwId);
384 ProviderTypes providerType = nw.get().getProviderNetworkType();
385 if (providerType == ProviderTypes.FLAT || providerType == ProviderTypes.VLAN) {
386 Uuid subnetId = NatUtil
387 .getFloatingIpPortSubnetIdFromFloatingIpId(dataBroker, floatingIpExternalId);
388 if (subnetId != null) {
393 Uuid vpnUuid = nw.get().getVpnid();
394 if (vpnUuid == null) {
395 LOG.error("getVpnId : Unable to read vpn from External network: {}", extNwId);
401 private Uint32 getVpnId(Uuid extNwId, Uuid floatingIpExternalId) {
402 Uuid vpnUuid = getVpnUuid(extNwId, floatingIpExternalId);
403 //Get the id using the VPN UUID (also vpn instance name)
404 return vpnUuid != null ? NatUtil.getVpnId(dataBroker, vpnUuid.getValue()) : NatConstants.INVALID_ID;
407 private void processFloatingIPAdd(final InstanceIdentifier<InternalToExternalPortMap> identifier,
408 final InternalToExternalPortMap mapping) {
409 LOG.trace("processFloatingIPAdd key: {}, value: {}", mapping.key(), mapping);
411 final String routerId = identifier.firstKeyOf(RouterPorts.class).getRouterId();
412 final PortsKey pKey = identifier.firstKeyOf(Ports.class);
413 String interfaceName = pKey.getPortName();
415 InstanceIdentifier<RouterPorts> portIid = identifier.firstIdentifierOf(RouterPorts.class);
416 coordinator.enqueueJob(NatConstants.NAT_DJC_PREFIX + mapping.key(), () -> Collections.singletonList(
417 txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
418 tx -> createNATFlowEntries(interfaceName, mapping, portIid, routerId, null, tx))),
419 NatConstants.NAT_DJC_MAX_RETRIES);
422 private void processFloatingIPDel(final InstanceIdentifier<InternalToExternalPortMap> identifier,
423 final InternalToExternalPortMap mapping) {
424 LOG.trace("processFloatingIPDel : key: {}, value: {}", mapping.key(), mapping);
426 final String routerId = identifier.firstKeyOf(RouterPorts.class).getRouterId();
427 final PortsKey pKey = identifier.firstKeyOf(Ports.class);
428 String interfaceName = pKey.getPortName();
430 InstanceIdentifier<RouterPorts> portIid = identifier.firstIdentifierOf(RouterPorts.class);
431 coordinator.enqueueJob(NatConstants.NAT_DJC_PREFIX + mapping.key(), () -> Collections.singletonList(
432 txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
433 tx -> removeNATFlowEntries(interfaceName, mapping, portIid, routerId, null, tx))),
434 NatConstants.NAT_DJC_MAX_RETRIES);
437 private InetAddress getInetAddress(String ipAddr) {
438 InetAddress ipAddress = null;
440 ipAddress = InetAddress.getByName(ipAddr);
441 } catch (UnknownHostException e) {
442 LOG.error("getInetAddress : UnknowHostException for ip {}", ipAddr, e);
447 private boolean validateIpMapping(InternalToExternalPortMap mapping) {
448 return getInetAddress(mapping.getInternalIp()) != null && getInetAddress(mapping.getExternalIp()) != null;
451 private Uint64 getAssociatedDpnWithExternalInterface(final String routerName, Uuid extNwId, Uint64 dpnId,
452 String interfaceName) {
453 //Get the DPN on which this interface resides
455 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
456 .state.Interface interfaceState = NatUtil.getInterfaceStateFromOperDS(dataBroker, interfaceName);
457 if (interfaceState != null) {
458 dpnId = NatUtil.getDpIdFromInterface(interfaceState);
461 Uint64 updatedDpnId = dpnId;
462 if (updatedDpnId != null && updatedDpnId.equals(Uint64.ZERO)) {
463 LOG.debug("getAssociatedDpnWithExternalInterface : The interface {} is not associated with any dpn",
467 ProviderTypes providerType = NatEvpnUtil.getExtNwProvTypeFromRouterName(dataBroker, routerName, extNwId);
468 if (providerType == null) {
469 LOG.warn("getAssociatedDpnWithExternalInterface : Provider Network Type for router {} and"
470 + " externalNetwork {} is missing.", routerName, extNwId);
474 // For FLAT and VLAN provider networks, we have to ensure that dpn hosting the VM has connectivity
475 // to External Network via provider_mappings. In case the dpn does not have the provider mappings,
476 // traffic from the VM has to be forwarded to the NAPT Switch (which is scheduled based on the provider
477 // mappings) and then sent out on the external Network.
478 if (providerType == ProviderTypes.FLAT || providerType == ProviderTypes.VLAN) {
479 String providerNet = NatUtil.getElanInstancePhysicalNetwok(extNwId.getValue(), dataBroker);
480 boolean isDpnConnected = natSwitchCache.isSwitchConnectedToExternal(updatedDpnId, providerNet);
481 if (!isDpnConnected) {
482 updatedDpnId = centralizedSwitchScheduler.getCentralizedSwitch(routerName);
488 void createNATFlowEntries(String interfaceName, final InternalToExternalPortMap mapping,
489 final InstanceIdentifier<RouterPorts> portIid, final String routerName, @Nullable Uint64 dpnId,
490 TypedReadWriteTransaction<Configuration> confTx) throws ExecutionException, InterruptedException {
491 if (!validateIpMapping(mapping)) {
492 LOG.error("createNATFlowEntries : Not a valid ip addresses in the mapping {}", mapping);
496 Uuid extNwId = getExtNetworkId(portIid, LogicalDatastoreType.CONFIGURATION);
497 if (extNwId == null) {
498 LOG.error("createNATFlowEntries : External network associated with interface {} could not be retrieved",
503 // For Overlay Networks, get the DPN on which this interface resides.
504 // For FLAT/VLAN Networks, get the DPN with provider_mappings for external network.
505 dpnId = getAssociatedDpnWithExternalInterface(routerName, extNwId, dpnId, interfaceName);
506 if (dpnId == null || dpnId.equals(Uint64.ZERO)) {
507 LOG.warn("createNATFlowEntries : No DPN for interface {}. NAT flow entries for ip mapping {} will "
508 + "not be installed", interfaceName, mapping);
512 Uint32 routerId = NatUtil.getVpnId(dataBroker, routerName);
513 if (routerId == NatConstants.INVALID_ID) {
514 LOG.error("createNATFlowEntries : Could not retrieve router id for {} to create NAT Flow entries",
518 //Check if the router to vpn association is present
519 //long associatedVpnId = NatUtil.getAssociatedVpn(dataBroker, routerName);
520 Uuid associatedVpn = NatUtil.getVpnForRouter(dataBroker, routerName);
521 Uint32 associatedVpnId = NatConstants.INVALID_ID;
522 if (associatedVpn == null) {
523 LOG.debug("createNATFlowEntries : Router {} is not assicated with any BGP VPN instance", routerName);
525 LOG.debug("createNATFlowEntries : Router {} is associated with VPN Instance with Id {}",
526 routerName, associatedVpn);
527 associatedVpnId = NatUtil.getVpnId(dataBroker, associatedVpn.getValue());
528 LOG.debug("createNATFlowEntries : vpninstance Id is {} for VPN {}", associatedVpnId, associatedVpn);
529 //routerId = associatedVpnId;
532 Uuid vpnUuid = getVpnUuid(extNwId, mapping.getExternalId());
534 LOG.trace("createNATFlowEntries : vpnUuid {} for External Network {}", vpnUuid, extNwId);
535 if (vpnUuid == null) {
536 LOG.error("createNATFlowEntries : No VPN associated with Ext nw {}. Unable to create SNAT table entry "
537 + "for fixed ip {}", extNwId, mapping.getInternalIp());
540 VpnInstance vpnInstance = NatUtil.getVpnIdToVpnInstance(dataBroker, vpnUuid.getValue());
541 if (vpnInstance == null || vpnInstance.getVpnId() == null) {
542 LOG.error("createNATFlowEntries : No VPN associated with Ext nw {}. Unable to create SNAT table entry "
543 + "for fixed ip {}", extNwId, mapping.getInternalIp());
546 //Install the DNAT default FIB flow L3_FIB_TABLE (21) -> PSNAT_TABLE (26) if SNAT is disabled
547 boolean isSnatEnabled = NatUtil.isSnatEnabledForRouterId(dataBroker, routerName);
548 if (!isSnatEnabled) {
549 addOrDelDefaultFibRouteForDnat(dpnId, routerName, routerId, confTx, true);
551 //Create the DNAT and SNAT table entries
552 Uint32 vpnId = vpnInstance.getVpnId();
553 String vrfId = vpnInstance.getVrfId();
554 createDNATTblEntry(dpnId, mapping, routerId, associatedVpnId, confTx);
555 createSNATTblEntry(dpnId, mapping, vpnId, routerId, associatedVpnId, extNwId, confTx);
556 floatingIPHandler.onAddFloatingIp(dpnId, routerName, routerId, extNwId, interfaceName, mapping,
560 void createNATFlowEntries(Uint64 dpnId, String interfaceName, String routerName, Uuid externalNetworkId,
561 InternalToExternalPortMap mapping, TypedReadWriteTransaction<Configuration> confTx)
562 throws ExecutionException, InterruptedException {
563 Uint32 routerId = NatUtil.getVpnId(dataBroker, routerName);
564 if (routerId == NatConstants.INVALID_ID) {
565 LOG.error("createNATFlowEntries : Could not retrieve router id for {} to create NAT Flow entries",
569 //Check if the router to vpn association is present
570 Uint32 associatedVpnId = NatUtil.getAssociatedVpn(dataBroker, routerName);
571 if (associatedVpnId == NatConstants.INVALID_ID) {
572 LOG.debug("createNATFlowEntries : Router {} is not assicated with any BGP VPN instance", routerName);
574 LOG.debug("createNATFlowEntries : Router {} is associated with VPN Instance with Id {}",
575 routerName, associatedVpnId);
576 //routerId = associatedVpnId;
579 Uuid vpnUuid = getVpnUuid(externalNetworkId, mapping.getExternalId());
580 LOG.trace("createNATFlowEntries : vpnUuid {} for External Network {}", vpnUuid, externalNetworkId);
581 if (vpnUuid == null) {
582 LOG.error("createNATFlowEntries : No vpnUuid associated with Ext nw {}. Unable to create SNAT table entry"
583 + " for fixed ip {}", externalNetworkId, mapping.getInternalIp());
586 VpnInstance vpnInstance = NatUtil.getVpnIdToVpnInstance(dataBroker, vpnUuid.getValue());
587 if (vpnInstance == null || vpnInstance.getVpnId() == null) {
588 LOG.error("createNATFlowEntries: VpnInstance associated with Ext nw {}. Unable to create SNAT table entry"
589 + " for fixed ip {}",externalNetworkId, mapping.getInternalIp());
592 //Install the DNAT default FIB flow L3_FIB_TABLE (21) -> PSNAT_TABLE (26) if SNAT is disabled
593 boolean isSnatEnabled = NatUtil.isSnatEnabledForRouterId(dataBroker, routerName);
594 if (!isSnatEnabled) {
595 addOrDelDefaultFibRouteForDnat(dpnId, routerName, routerId, confTx, true);
597 //Create the DNAT and SNAT table entries
598 Uint32 vpnId = vpnInstance.getVpnId();
599 String vrfId = vpnInstance.getVrfId();
600 createDNATTblEntry(dpnId, mapping, routerId, associatedVpnId, confTx);
601 createSNATTblEntry(dpnId, mapping, vpnId, routerId, associatedVpnId, externalNetworkId, confTx);
602 floatingIPHandler.onAddFloatingIp(dpnId, routerName, routerId, externalNetworkId, interfaceName, mapping,
606 void createNATOnlyFlowEntries(Uint64 dpnId, String routerName, @Nullable String associatedVPN,
607 Uuid externalNetworkId, InternalToExternalPortMap mapping)
608 throws ExecutionException, InterruptedException {
609 //String segmentId = associatedVPN == null ? routerName : associatedVPN;
610 LOG.debug("createNATOnlyFlowEntries : Retrieving vpn id for VPN {} to proceed with create NAT Flows",
612 Uint32 routerId = NatUtil.getVpnId(dataBroker, routerName);
613 if (routerId == NatConstants.INVALID_ID) {
614 LOG.error("createNATOnlyFlowEntries : Could not retrieve vpn id for {} to create NAT Flow entries",
618 Uint32 associatedVpnId = NatUtil.getVpnId(dataBroker, associatedVPN);
619 LOG.debug("createNATOnlyFlowEntries : Associated VPN Id {} for router {}", associatedVpnId, routerName);
620 Uint32 vpnId = getVpnId(externalNetworkId, mapping.getExternalId());
621 if (vpnId.longValue() < 0) {
622 LOG.error("createNATOnlyFlowEntries : Unable to create SNAT table entry for fixed ip {}",
623 mapping.getInternalIp());
626 //Install the DNAT default FIB flow L3_FIB_TABLE (21) -> PSNAT_TABLE (26) if SNAT is disabled
627 boolean isSnatEnabled = NatUtil.isSnatEnabledForRouterId(dataBroker, routerName);
628 if (!isSnatEnabled) {
629 addOrDelDefaultFibRouteForDnat(dpnId, routerName, routerId, null, true);
631 //Create the DNAT and SNAT table entries
632 FlowEntity preFlowEntity = buildPreDNATFlowEntity(dpnId, mapping, routerId, associatedVpnId);
633 mdsalManager.installFlow(preFlowEntity);
635 FlowEntity flowEntity = buildDNATFlowEntity(dpnId, mapping, routerId, associatedVpnId);
636 mdsalManager.installFlow(flowEntity);
638 String externalIp = mapping.getExternalIp();
639 preFlowEntity = buildPreSNATFlowEntity(dpnId, mapping.getInternalIp(), externalIp, vpnId,
640 routerId, associatedVpnId);
641 mdsalManager.installFlow(preFlowEntity);
643 flowEntity = buildSNATFlowEntity(dpnId, mapping, vpnId, externalNetworkId);
644 if (flowEntity != null) {
645 mdsalManager.installFlow(flowEntity);
650 void removeNATFlowEntries(String interfaceName, final InternalToExternalPortMap mapping,
651 InstanceIdentifier<RouterPorts> portIid, final String routerName, @Nullable Uint64 dpnId,
652 TypedReadWriteTransaction<Configuration> removeFlowInvTx) throws ExecutionException, InterruptedException {
653 Uuid extNwId = getExtNetworkId(portIid, LogicalDatastoreType.OPERATIONAL);
654 if (extNwId == null) {
655 LOG.error("removeNATFlowEntries : External network associated with interface {} could not be retrieved",
660 // For Overlay Networks, get the DPN on which this interface resides.
661 // For FLAT/VLAN Networks, get the DPN with provider_mappings for external network.
663 dpnId = getAssociatedDpnWithExternalInterface(routerName, extNwId,
664 NatUtil.getDpnForInterface(interfaceManager, interfaceName), interfaceName);
665 if (dpnId == null || dpnId.equals(Uint64.ZERO)) {
666 LOG.warn("removeNATFlowEntries: Abort processing Floating ip configuration. No DPN for port: {}",
672 Uint32 routerId = NatUtil.getVpnId(dataBroker, routerName);
673 if (routerId == NatConstants.INVALID_ID) {
674 LOG.error("removeNATFlowEntries : Could not retrieve router id for {} to remove NAT Flow entries",
679 String internalIp = mapping.getInternalIp();
680 String externalIp = mapping.getExternalIp();
682 //Delete the DNAT and SNAT table entries
683 removeDNATTblEntry(dpnId, internalIp, externalIp, routerId, removeFlowInvTx);
684 Uuid vpnUuid = getVpnUuid(extNwId, mapping.getExternalId());
685 if (vpnUuid == null) {
686 LOG.error("removeNATFlowEntries : No VPN associated with Ext nw {}. Unable to remove SNAT table entry "
687 + "for fixed ip {}", extNwId, mapping.getInternalIp());
690 VpnInstance vpnInstance = NatUtil.getVpnIdToVpnInstance(dataBroker, vpnUuid.getValue());
691 if (vpnInstance == null || vpnInstance.getVpnId() == null) {
692 LOG.error("removeNATFlowEntries: No VPN associated with Ext nw {}. Unable to create SNAT table entry "
693 + "for fixed ip {}", extNwId, mapping.getInternalIp());
696 Uint32 vpnId = vpnInstance.getVpnId();
697 String vrfId = vpnInstance.getVrfId();
698 removeSNATTblEntry(dpnId, internalIp, externalIp, routerId, vpnId, removeFlowInvTx);
699 //Remove the DNAT default FIB flow L3_FIB_TABLE (21) -> PSNAT_TABLE (26) if SNAT is disabled
700 boolean isSnatEnabled = NatUtil.isSnatEnabledForRouterId(dataBroker, routerName);
701 if (!isSnatEnabled) {
702 addOrDelDefaultFibRouteForDnat(dpnId, routerName, routerId, removeFlowInvTx, false);
704 ProviderTypes provType = NatEvpnUtil.getExtNwProvTypeFromRouterName(dataBroker, routerName, extNwId);
705 if (provType == null) {
706 LOG.error("removeNATFlowEntries : External Network Provider Type missing");
709 if (provType == ProviderTypes.VXLAN) {
710 floatingIPHandler.onRemoveFloatingIp(dpnId, routerName, routerId, extNwId, mapping,
711 NatConstants.DEFAULT_L3VNI_VALUE, vrfId, removeFlowInvTx);
712 removeOperationalDS(routerName, interfaceName, internalIp);
715 Uint32 label = getOperationalIpMapping(routerName, interfaceName, internalIp);
716 if (label.longValue() < 0) {
717 LOG.error("removeNATFlowEntries : Could not retrieve label for prefix {} in router {}",
718 internalIp, routerId);
721 floatingIPHandler.onRemoveFloatingIp(dpnId, routerName, routerId, extNwId, mapping, label, vrfId,
723 removeOperationalDS(routerName, interfaceName, internalIp);
726 void removeNATFlowEntries(Uint64 dpnId, String interfaceName, String vpnName, String routerName,
727 InternalToExternalPortMap mapping, TypedReadWriteTransaction<Configuration> confTx)
728 throws ExecutionException, InterruptedException {
729 String internalIp = mapping.getInternalIp();
730 String externalIp = mapping.getExternalIp();
731 Uint32 routerId = NatUtil.getVpnId(dataBroker, routerName);
732 if (routerId == NatConstants.INVALID_ID) {
733 LOG.error("removeNATFlowEntries : Could not retrieve router id for {} to remove NAT Flow entries",
738 VpnInstance vpnInstance = NatUtil.getVpnIdToVpnInstance(dataBroker, vpnName);
739 if (vpnInstance == null || vpnInstance.getVpnId() == null) {
740 LOG.warn("removeNATFlowEntries: VPN Id not found for {} to remove NAT flow entries {}",
741 vpnName, internalIp);
744 Uint32 vpnId = vpnInstance.getVpnId();
745 String vrfId = vpnInstance.getVrfId();
747 //Delete the DNAT and SNAT table entries
748 removeDNATTblEntry(dpnId, internalIp, externalIp, routerId, confTx);
749 removeSNATTblEntry(dpnId, internalIp, externalIp, routerId, vpnId, confTx);
750 //Remove the DNAT default FIB flow L3_FIB_TABLE (21) -> PSNAT_TABLE (26) if SNAT is disabled
751 boolean isSnatEnabled = NatUtil.isSnatEnabledForRouterId(dataBroker, routerName);
752 if (!isSnatEnabled) {
753 addOrDelDefaultFibRouteForDnat(dpnId, routerName, routerId, confTx, false);
755 Uuid externalNetworkId = NatUtil.getNetworkIdFromRouterName(dataBroker,routerName);
756 ProviderTypes provType = NatEvpnUtil.getExtNwProvTypeFromRouterName(dataBroker, routerName, externalNetworkId);
757 if (provType == null) {
758 LOG.error("removeNATFlowEntries : External Network Provider Type Missing");
761 if (provType == ProviderTypes.VXLAN) {
762 floatingIPHandler.cleanupFibEntries(dpnId, vpnName, externalIp, NatConstants.DEFAULT_L3VNI_VALUE, vrfId,
764 removeOperationalDS(routerName, interfaceName, internalIp);
767 Uint32 label = getOperationalIpMapping(routerName, interfaceName, internalIp);
768 if (label != null && label.longValue() < 0) {
769 LOG.error("removeNATFlowEntries : Could not retrieve label for prefix {} in router {}",
770 internalIp, routerId);
773 if (provType == ProviderTypes.VXLAN) {
774 floatingIPHandler.cleanupFibEntries(dpnId, vpnName, externalIp, NatConstants.DEFAULT_L3VNI_VALUE, vrfId,
776 removeOperationalDS(routerName, interfaceName, internalIp);
779 floatingIPHandler.cleanupFibEntries(dpnId, vpnName, externalIp, label, vrfId, confTx, provType);
780 removeOperationalDS(routerName, interfaceName, internalIp);
783 protected Uint32 getOperationalIpMapping(String routerId, String interfaceName, String internalIp) {
784 InstanceIdentifier<InternalToExternalPortMap> intExtPortMapIdentifier =
785 NatUtil.getIntExtPortMapIdentifier(routerId, interfaceName, internalIp);
786 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
787 LogicalDatastoreType.OPERATIONAL, intExtPortMapIdentifier).map(
788 InternalToExternalPortMap::getLabel).orElse(NatConstants.INVALID_ID);
791 static void updateOperationalDS(DataBroker dataBroker, String routerId, String interfaceName, Uint32 label,
792 String internalIp, String externalIp) {
794 LOG.info("updateOperationalDS : Updating operational DS for floating ip config : {} with label {}",
796 InstanceIdentifier<Ports> portsId = NatUtil.getPortsIdentifier(routerId, interfaceName);
797 Optional<Ports> optPorts =
798 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
799 LogicalDatastoreType.OPERATIONAL, portsId);
800 InternalToExternalPortMap intExtPortMap = new InternalToExternalPortMapBuilder().withKey(new
801 InternalToExternalPortMapKey(internalIp)).setInternalIp(internalIp).setExternalIp(externalIp)
802 .setLabel(label).build();
803 if (optPorts.isPresent()) {
804 LOG.debug("updateOperationalDS : Ports {} entry already present. Updating intExtPortMap for internal ip {}",
805 interfaceName, internalIp);
806 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, portsId.child(InternalToExternalPortMap
807 .class, new InternalToExternalPortMapKey(internalIp)), intExtPortMap);
809 LOG.debug("updateOperationalDS : Adding Ports entry {} along with intExtPortMap {}",
810 interfaceName, internalIp);
811 List<InternalToExternalPortMap> intExtPortMapList = new ArrayList<>();
812 intExtPortMapList.add(intExtPortMap);
813 Ports ports = new PortsBuilder().withKey(new PortsKey(interfaceName)).setPortName(interfaceName)
814 .setInternalToExternalPortMap(intExtPortMapList).build();
815 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, portsId, ports);
819 void removeOperationalDS(String routerId, String interfaceName, String internalIp) {
820 LOG.info("removeOperationalDS : Remove operational DS for floating ip config: {}", internalIp);
821 InstanceIdentifier<InternalToExternalPortMap> intExtPortMapId = NatUtil.getIntExtPortMapIdentifier(routerId,
822 interfaceName, internalIp);
823 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.OPERATIONAL, intExtPortMapId);
826 private FlowEntity buildPreDNATDeleteFlowEntity(Uint64 dpId, String externalIp, Uint32 routerId) {
828 LOG.info("buildPreDNATDeleteFlowEntity : Bulding Delete DNAT Flow entity for ip {} ", externalIp);
830 String flowRef = NatUtil.getFlowRef(dpId, NwConstants.PDNAT_TABLE, routerId, externalIp);
832 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.PDNAT_TABLE, flowRef,
833 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
834 NwConstants.COOKIE_DNAT_TABLE, null, null);
841 private FlowEntity buildDNATDeleteFlowEntity(Uint64 dpId, String internalIp, Uint32 routerId) {
843 LOG.info("buildDNATDeleteFlowEntity : Bulding Delete DNAT Flow entity for ip {} ", internalIp);
845 String flowRef = NatUtil.getFlowRef(dpId, NwConstants.DNAT_TABLE, routerId, internalIp);
847 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.DNAT_TABLE, flowRef,
848 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
849 NwConstants.COOKIE_DNAT_TABLE, null, null);
855 private FlowEntity buildPreSNATDeleteFlowEntity(Uint64 dpId, String internalIp, Uint32 routerId) {
857 LOG.info("buildPreSNATDeleteFlowEntity : Building Delete PSNAT Flow entity for ip {} ", internalIp);
859 String flowRef = NatUtil.getFlowRef(dpId, NwConstants.PSNAT_TABLE, routerId, internalIp);
861 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.PSNAT_TABLE, flowRef,
862 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
863 NwConstants.COOKIE_DNAT_TABLE, null, null);
867 private FlowEntity buildSNATDeleteFlowEntity(Uint64 dpId, String externalIp, Uint32 routerId) {
869 LOG.info("buildSNATDeleteFlowEntity : Building Delete SNAT Flow entity for ip {} ", externalIp);
871 String flowRef = NatUtil.getFlowRef(dpId, NwConstants.SNAT_TABLE, routerId, externalIp);
873 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.SNAT_TABLE, flowRef,
874 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
875 NwConstants.COOKIE_DNAT_TABLE, null, null);
880 private void addOrDelDefaultFibRouteForDnat(Uint64 dpnId, String routerName, Uint32 routerId,
881 @Nullable TypedReadWriteTransaction<Configuration> confTx, boolean create)
882 throws ExecutionException, InterruptedException {
883 if (confTx == null) {
884 ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
885 newTx -> addOrDelDefaultFibRouteForDnat(dpnId, routerName, routerId, newTx, create)), LOG,
886 "Error handling default FIB route for DNAT");
889 //Check if the router to bgp-vpn association is present
890 Uint32 associatedVpnId = NatConstants.INVALID_ID;
891 Uuid associatedVpn = NatUtil.getVpnForRouter(dataBroker, routerName);
892 if (associatedVpn != null) {
893 associatedVpnId = NatUtil.getVpnId(dataBroker, associatedVpn.getValue());
896 if (associatedVpnId != NatConstants.INVALID_ID) {
897 LOG.debug("addOrDelDefaultFibRouteForDnat: Install NAT default route on DPN {} for the router {} with "
898 + "vpn-id {}", dpnId, routerName, associatedVpnId);
899 defaultRouteProgrammer.installDefNATRouteInDPN(dpnId, associatedVpnId, routerId, confTx);
901 LOG.debug("addOrDelDefaultFibRouteForDnat: Install NAT default route on DPN {} for the router {} with "
902 + "vpn-id {}", dpnId, routerName, routerId);
903 defaultRouteProgrammer.installDefNATRouteInDPN(dpnId, routerId, confTx);
906 if (associatedVpnId != NatConstants.INVALID_ID) {
907 LOG.debug("addOrDelDefaultFibRouteForDnat: Remove NAT default route on DPN {} for the router {} "
908 + "with vpn-id {}", dpnId, routerName, associatedVpnId);
909 defaultRouteProgrammer.removeDefNATRouteInDPN(dpnId, associatedVpnId, routerId, confTx);
911 LOG.debug("addOrDelDefaultFibRouteForDnat: Remove NAT default route on DPN {} for the router {} "
912 + "with vpn-id {}", dpnId, routerName, routerId);
913 defaultRouteProgrammer.removeDefNATRouteInDPN(dpnId, routerId, confTx);