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
8 package org.opendaylight.netvirt.natservice.internal;
10 import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
12 import com.google.common.base.Optional;
13 import java.math.BigInteger;
14 import java.util.Collection;
15 import java.util.Collections;
16 import java.util.List;
18 import java.util.concurrent.ExecutionException;
19 import javax.annotation.PostConstruct;
20 import javax.inject.Inject;
21 import javax.inject.Singleton;
22 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
23 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
24 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
25 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
26 import org.opendaylight.genius.infra.Datastore.Configuration;
27 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
28 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
29 import org.opendaylight.genius.infra.TypedReadWriteTransaction;
30 import org.opendaylight.genius.mdsalutil.BucketInfo;
31 import org.opendaylight.genius.mdsalutil.FlowEntity;
32 import org.opendaylight.genius.mdsalutil.GroupEntity;
33 import org.opendaylight.genius.mdsalutil.MDSALUtil;
34 import org.opendaylight.genius.mdsalutil.NwConstants;
35 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
36 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
37 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
38 import org.opendaylight.netvirt.natservice.api.SnatServiceManager;
39 import org.opendaylight.netvirt.neutronvpn.interfaces.INeutronVpnManager;
40 import org.opendaylight.serviceutils.upgrade.UpgradeState;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.NeutronRouterDpns;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnList;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesList;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.config.rev170206.NatserviceConfig;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.config.rev170206.NatserviceConfig.NatMode;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
51 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
56 public class RouterDpnChangeListener
57 extends AsyncDataTreeChangeListenerBase<DpnVpninterfacesList, RouterDpnChangeListener> {
59 private static final Logger LOG = LoggerFactory.getLogger(RouterDpnChangeListener.class);
60 private final DataBroker dataBroker;
61 private final ManagedNewTransactionRunner txRunner;
62 private final IMdsalApiManager mdsalManager;
63 private final SNATDefaultRouteProgrammer snatDefaultRouteProgrammer;
64 private final NaptSwitchHA naptSwitchHA;
65 private final IdManagerService idManager;
66 private final INeutronVpnManager nvpnManager;
67 private final ExternalNetworkGroupInstaller extNetGroupInstaller;
68 private final JobCoordinator coordinator;
69 private final SnatServiceManager natServiceManager;
70 private final NatMode natMode;
71 private final UpgradeState upgradeState;
74 public RouterDpnChangeListener(final DataBroker dataBroker, final IMdsalApiManager mdsalManager,
75 final SNATDefaultRouteProgrammer snatDefaultRouteProgrammer,
76 final NaptSwitchHA naptSwitchHA,
77 final IdManagerService idManager,
78 final ExternalNetworkGroupInstaller extNetGroupInstaller,
79 final INeutronVpnManager nvpnManager,
80 final SnatServiceManager natServiceManager,
81 final NatserviceConfig config,
82 final JobCoordinator coordinator,
83 final UpgradeState upgradeState) {
84 super(DpnVpninterfacesList.class, RouterDpnChangeListener.class);
85 this.dataBroker = dataBroker;
86 this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
87 this.mdsalManager = mdsalManager;
88 this.snatDefaultRouteProgrammer = snatDefaultRouteProgrammer;
89 this.naptSwitchHA = naptSwitchHA;
90 this.idManager = idManager;
91 this.extNetGroupInstaller = extNetGroupInstaller;
92 this.nvpnManager = nvpnManager;
93 this.natServiceManager = natServiceManager;
94 this.coordinator = coordinator;
95 this.natMode = config != null ? config.getNatMode() : NatMode.Controller;
96 this.upgradeState = upgradeState;
102 LOG.info("{} init", getClass().getSimpleName());
103 registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
107 protected RouterDpnChangeListener getDataTreeChangeListener() {
108 return RouterDpnChangeListener.this;
112 protected InstanceIdentifier<DpnVpninterfacesList> getWildCardPath() {
113 return InstanceIdentifier.create(NeutronRouterDpns.class).child(RouterDpnList.class)
114 .child(DpnVpninterfacesList.class);
118 protected void add(final InstanceIdentifier<DpnVpninterfacesList> identifier, final DpnVpninterfacesList dpnInfo) {
119 LOG.trace("add : key: {}, value: {}", dpnInfo.key(), dpnInfo);
120 final String routerUuid = identifier.firstKeyOf(RouterDpnList.class).getRouterId();
121 BigInteger dpnId = dpnInfo.getDpnId();
122 //check router is associated to external network
123 InstanceIdentifier<Routers> id = NatUtil.buildRouterIdentifier(routerUuid);
124 Optional<Routers> routerData =
125 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
126 LogicalDatastoreType.CONFIGURATION, id);
127 if (routerData.isPresent()) {
128 Routers router = routerData.get();
129 Uuid networkId = router.getNetworkId();
130 if (networkId != null) {
131 if (natMode == NatMode.Conntrack) {
132 BigInteger naptSwitch = NatUtil.getPrimaryNaptfromRouterName(dataBroker, router.getRouterName());
133 if (naptSwitch == null || naptSwitch.equals(BigInteger.ZERO)) {
134 LOG.warn("add : NAPT switch is not selected.");
137 //If it is for NAPT switch skip as the flows would be already programmed.
138 if (naptSwitch.equals(dpnId)) {
139 LOG.debug("Skipping the notification recived for NAPT switch {}", routerUuid);
142 ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
144 natServiceManager.notify(confTx, router, null, naptSwitch, dpnId,
145 SnatServiceManager.Action.CNT_ROUTER_ENBL);
146 if (router.isEnableSnat()) {
147 natServiceManager.notify(confTx, router, null, naptSwitch, naptSwitch,
148 SnatServiceManager.Action.SNAT_ROUTER_ENBL);
150 }), LOG, "Error notifying NAT service manager");
152 Long routerId = NatUtil.getVpnId(dataBroker, routerUuid);
153 if (routerId == NatConstants.INVALID_ID) {
154 LOG.error("add : Invalid routerId returned for routerName {}", routerUuid);
157 ProviderTypes extNwProvType = NatEvpnUtil.getExtNwProvTypeFromRouterName(dataBroker,
158 routerUuid, networkId);
159 if (extNwProvType == ProviderTypes.FLAT || extNwProvType == ProviderTypes.VLAN) {
160 coordinator.enqueueJob(NatConstants.NAT_DJC_PREFIX + networkId, () -> {
161 extNetGroupInstaller.installExtNetGroupEntries(networkId, dpnId);
162 installDefaultNatRouteForRouterExternalSubnets(dpnId,
163 NatUtil.getExternalSubnetIdsFromExternalIps(router.getExternalIps()));
164 return Collections.emptyList();
167 coordinator.enqueueJob(NatConstants.NAT_DJC_PREFIX + router.getRouterName(), () -> {
168 LOG.debug("add : Router {} is associated with ext nw {}", routerUuid, networkId);
169 Uuid vpnName = NatUtil.getVpnForRouter(dataBroker, routerUuid);
170 return Collections.singletonList(
171 txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, confTx -> {
173 if (vpnName == null) {
174 LOG.debug("add : Internal vpn associated to router {}", routerUuid);
176 if (vpnId == NatConstants.INVALID_ID) {
177 LOG.error("add : Invalid vpnId returned for routerName {}", routerUuid);
180 LOG.debug("add : Retrieved vpnId {} for router {}", vpnId, routerUuid);
181 //Install default entry in FIB to SNAT table
183 "add : Installing default route in FIB on dpn {} for router {} with vpn {}",
184 dpnId, routerUuid, vpnId);
185 snatDefaultRouteProgrammer.installDefNATRouteInDPN(dpnId, vpnId, confTx);
187 LOG.debug("add : External BGP vpn associated to router {}", routerUuid);
188 vpnId = NatUtil.getVpnId(dataBroker, vpnName.getValue());
189 if (vpnId == NatConstants.INVALID_ID) {
190 LOG.error("add : Invalid vpnId returned for routerName {}", routerUuid);
193 LOG.debug("add : Retrieved vpnId {} for router {}", vpnId, routerUuid);
194 //Install default entry in FIB to SNAT table
195 LOG.debug("add : Installing default route in FIB on dpn {} for routerId {} with "
196 + "vpnId {}...", dpnId, routerUuid, vpnId);
197 snatDefaultRouteProgrammer.installDefNATRouteInDPN(dpnId, vpnId, routerId, confTx);
199 /* install V6 internet default fallback rule in FIB_TABLE if router
200 * is having V6 subnet
202 nvpnManager.programV6InternetFallbackFlow(new Uuid(routerUuid),
203 NatUtil.getVpnIdfromNetworkId(dataBroker, networkId), NwConstants.ADD_FLOW);
204 if (router.isEnableSnat()) {
205 LOG.info("add : SNAT enabled for router {}", routerUuid);
206 if (extNwProvType == null) {
207 LOG.error("add : External Network Provider Type missing");
210 handleSNATForDPN(dpnId, routerUuid, routerId, vpnId, confTx);
212 LOG.info("add : SNAT is not enabled for router {} to handle addDPN event {}",
216 }, NatConstants.NAT_DJC_MAX_RETRIES);
217 } // end of controller based SNAT
220 LOG.debug("add : Router {} is not associated with External network", routerUuid);
225 protected void remove(InstanceIdentifier<DpnVpninterfacesList> identifier, DpnVpninterfacesList dpnInfo) {
226 LOG.trace("remove : key: {}, value: {}", dpnInfo.key(), dpnInfo);
227 final String routerUuid = identifier.firstKeyOf(RouterDpnList.class).getRouterId();
228 Long routerId = NatUtil.getVpnId(dataBroker, routerUuid);
229 if (routerId == NatConstants.INVALID_ID) {
230 LOG.error("REMOVE: Invalid routId returned for routerName {}",routerUuid);
233 BigInteger dpnId = dpnInfo.getDpnId();
234 //check router is associated to external network
235 InstanceIdentifier<Routers> id = NatUtil.buildRouterIdentifier(routerUuid);
236 Optional<Routers> routerData =
237 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
238 LogicalDatastoreType.CONFIGURATION, id);
239 if (routerData.isPresent()) {
240 Routers router = routerData.get();
241 Uuid networkId = router.getNetworkId();
242 if (networkId != null) {
243 if (natMode == NatMode.Conntrack) {
244 BigInteger naptSwitch = NatUtil.getPrimaryNaptfromRouterName(dataBroker, router.getRouterName());
245 if (naptSwitch == null || naptSwitch.equals(BigInteger.ZERO)) {
246 LOG.warn("remove : NAPT switch is not selected.");
249 //If it is for NAPT switch skip as the flows would be already programmed.
250 if (naptSwitch.equals(dpnId)) {
251 LOG.debug("Skipping the notification recived for NAPT switch {}", routerUuid);
254 ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
256 natServiceManager.notify(confTx, router, null, naptSwitch, dpnId,
257 SnatServiceManager.Action.CNT_ROUTER_DISBL);
258 if (router.isEnableSnat()) {
259 natServiceManager.notify(confTx, router, null, naptSwitch, naptSwitch,
260 SnatServiceManager.Action.SNAT_ROUTER_DISBL);
262 }), LOG, "Error notifying NAT service manager");
264 coordinator.enqueueJob(NatConstants.NAT_DJC_PREFIX + routerUuid, () -> {
265 LOG.debug("remove : Router {} is associated with ext nw {}", routerUuid, networkId);
266 Uuid vpnName = NatUtil.getVpnForRouter(dataBroker, routerUuid);
267 return Collections.singletonList(
268 txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, confTx -> {
270 if (vpnName == null) {
271 LOG.debug("remove : Internal vpn associated to router {}", routerUuid);
273 if (vpnId == NatConstants.INVALID_ID) {
274 LOG.error("remove : Invalid vpnId returned for routerName {}", routerUuid);
277 LOG.debug("remove : Retrieved vpnId {} for router {}", vpnId, routerUuid);
278 //Remove default entry in FIB
279 LOG.debug("remove : Removing default route in FIB on dpn {} ...", dpnId);
280 snatDefaultRouteProgrammer.removeDefNATRouteInDPN(dpnId, vpnId, confTx);
282 LOG.debug("remove : External vpn associated to router {}", routerUuid);
283 vpnId = NatUtil.getVpnId(dataBroker, vpnName.getValue());
284 if (vpnId == NatConstants.INVALID_ID) {
285 LOG.error("remove : Invalid vpnId returned for routerName {}", routerUuid);
288 LOG.debug("remove : Retrieved vpnId {} for router {}", vpnId, routerUuid);
289 //Remove default entry in FIB
290 LOG.debug("remove : Removing default route in FIB on dpn {} for vpn {} ...", dpnId,
292 snatDefaultRouteProgrammer.removeDefNATRouteInDPN(dpnId, vpnId, routerId, confTx);
294 /* remove V6 internet default fallback rule in FIB_TABLE if router
295 * is having V6 subnet
297 nvpnManager.programV6InternetFallbackFlow(new Uuid(routerUuid),
298 NatUtil.getVpnIdfromNetworkId(dataBroker, networkId), NwConstants.DEL_FLOW);
299 if (router.isEnableSnat()) {
300 LOG.info("remove : SNAT enabled for router {}", routerUuid);
301 removeSNATFromDPN(dpnId, routerUuid, routerId, vpnId, networkId, confTx);
303 LOG.info("remove : SNAT is not enabled for router {} to handle removeDPN event {}",
307 }, NatConstants.NAT_DJC_MAX_RETRIES);
308 } // end of controller based SNAT
314 protected void update(InstanceIdentifier<DpnVpninterfacesList> identifier, DpnVpninterfacesList original,
315 DpnVpninterfacesList update) {
316 LOG.trace("Update key: {}, original: {}, update: {}", update.key(), original, update);
319 void handleSNATForDPN(BigInteger dpnId, String routerName, long routerId, Long routerVpnId,
320 TypedReadWriteTransaction<Configuration> confTx) {
321 //Check if primary and secondary switch are selected, If not select the role
322 //Install select group to NAPT switch
323 //Install default miss entry to NAPT switch
324 BigInteger naptSwitch;
326 BigInteger naptId = NatUtil.getPrimaryNaptfromRouterName(dataBroker, routerName);
327 if (naptId == null || naptId.equals(BigInteger.ZERO)
328 || !NatUtil.getSwitchStatus(dataBroker, naptId) && !upgradeState.isUpgradeInProgress()) {
329 LOG.debug("handleSNATForDPN : NaptSwitch is down or not selected for router {},naptId {}",
332 boolean naptstatus = naptSwitchHA.updateNaptSwitch(routerName, naptSwitch);
334 LOG.error("handleSNATForDPN : Failed to update newNaptSwitch {} for routername {}",
335 naptSwitch, routerName);
338 LOG.debug("handleSNATForDPN : Switch {} is elected as NaptSwitch for router {}", dpnId, routerName);
339 Routers extRouters = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
340 if (extRouters != null) {
341 NatUtil.createRouterIdsConfigDS(dataBroker, routerId, routerName);
342 naptSwitchHA.subnetRegisterMapping(extRouters, routerId);
345 naptSwitchHA.installSnatFlows(routerName, routerId, naptSwitch, routerVpnId, confTx);
347 // Install miss entry (table 26) pointing to table 46
348 FlowEntity flowEntity = naptSwitchHA.buildSnatFlowEntityForNaptSwitch(dpnId, routerName,
349 routerVpnId, NatConstants.ADD_FLOW);
350 if (flowEntity == null) {
351 LOG.error("handleSNATForDPN : Failed to populate flowentity for router {} with dpnId {}",
355 LOG.debug("handleSNATForDPN : Successfully installed flow for dpnId {} router {}", dpnId, routerName);
356 mdsalManager.addFlow(confTx, flowEntity);
357 //Removing primary flows from old napt switch
358 if (naptId != null && !naptId.equals(BigInteger.ZERO)) {
359 LOG.debug("handleSNATForDPN : Removing primary flows from old napt switch {} for router {}",
361 naptSwitchHA.removeSnatFlowsInOldNaptSwitch(routerName, routerId, naptId, null, confTx);
363 } else if (naptId.equals(dpnId)) {
364 LOG.debug("handleSNATForDPN : NaptSwitch {} gone down during cluster reboot came alive", naptId);
367 LOG.debug("handleSNATForDPN : Napt switch with Id {} is already elected for router {}",
371 List<BucketInfo> bucketInfo = naptSwitchHA.handleGroupInNeighborSwitches(dpnId,
372 routerName, routerId, naptSwitch);
373 naptSwitchHA.installSnatGroupEntry(dpnId, bucketInfo, routerName);
375 // Install miss entry (table 26) pointing to group
376 long groupId = NatUtil.getUniqueId(idManager, NatConstants.SNAT_IDPOOL_NAME,
377 NatUtil.getGroupIdKey(routerName));
378 if (groupId != NatConstants.INVALID_ID) {
379 FlowEntity flowEntity =
380 naptSwitchHA.buildSnatFlowEntity(dpnId, routerName, groupId,
381 routerVpnId, NatConstants.ADD_FLOW);
382 if (flowEntity == null) {
384 "handleSNATForDPN : Failed to populate flowentity for router {} with dpnId {} groupId {}",
385 routerName, dpnId, groupId);
389 "handleSNATForDPN : Successfully installed flow for dpnId {} router {} group {}",
390 dpnId, routerName, groupId);
391 mdsalManager.addFlow(confTx, flowEntity);
393 LOG.error("handleSNATForDPN : Failed to Obtain groupId for router {}", routerName);
396 } catch (InterruptedException | ExecutionException e) {
397 LOG.error("handleSNATForDPN : Exception in handleSNATForDPN", e);
401 // TODO Clean up the exception handling
402 @SuppressWarnings("checkstyle:IllegalCatch")
403 void removeSNATFromDPN(BigInteger dpnId, String routerName, long routerId, long routerVpnId,
404 Uuid extNetworkId, TypedReadWriteTransaction<Configuration> confTx) {
405 //irrespective of naptswitch or non-naptswitch, SNAT default miss entry need to be removed
406 //remove miss entry to NAPT switch
407 //if naptswitch elect new switch and install Snat flows and remove those flows in oldnaptswitch
409 Collection<String> externalIpCache = NatUtil.getExternalIpsForRouter(dataBroker, routerId);
410 ProviderTypes extNwProvType = NatEvpnUtil.getExtNwProvTypeFromRouterName(dataBroker, routerName, extNetworkId);
411 if (extNwProvType == null) {
414 //Get the external IP labels other than VXLAN provider type. Since label is not applicable for VXLAN
415 Map<String, Long> externalIpLabel;
416 if (extNwProvType == ProviderTypes.VXLAN) {
417 externalIpLabel = null;
419 externalIpLabel = NatUtil.getExternalIpsLabelForRouter(dataBroker, routerId);
421 BigInteger naptSwitch = NatUtil.getPrimaryNaptfromRouterName(dataBroker, routerName);
422 if (naptSwitch == null || naptSwitch.equals(BigInteger.ZERO)) {
423 LOG.error("removeSNATFromDPN : No naptSwitch is selected for router {}", routerName);
428 naptSwitchHA.isNaptSwitchDown(routerName, routerId, dpnId, naptSwitch, routerVpnId,
429 externalIpCache, confTx);
431 LOG.debug("removeSNATFromDPN: Switch with DpnId {} is not naptSwitch for router {}",
433 FlowEntity flowEntity = null;
434 long groupId = NatUtil.getUniqueId(idManager, NatConstants.SNAT_IDPOOL_NAME,
435 NatUtil.getGroupIdKey(routerName));
438 if (groupId != NatConstants.INVALID_ID) {
439 flowEntity = naptSwitchHA
440 .buildSnatFlowEntity(dpnId, routerName, groupId, routerVpnId,
441 NatConstants.DEL_FLOW);
442 if (flowEntity == null) {
443 LOG.error("removeSNATFromDPN : Failed to populate flowentity for router:{} "
444 + "with dpnId:{} groupId:{}", routerName, dpnId, groupId);
447 LOG.debug("removeSNATFromDPN : Removing default SNAT miss entry flow entity {}",
449 mdsalManager.removeFlow(confTx, flowEntity);
451 LOG.error("removeSNATFromDPN : Failed to Obtained Groupid for Router {}", routerName);
453 } catch (Exception ex) {
454 LOG.error("removeSNATFromDPN : Failed to remove default SNAT miss entry flow entity {}",
458 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routername {}",
462 GroupEntity groupEntity = null;
464 groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, routerName,
465 GroupTypes.GroupAll, Collections.emptyList() /*listBucketInfo*/);
466 LOG.info("removeSNATFromDPN : Removing NAPT GroupEntity:{}", groupEntity);
467 mdsalManager.removeGroup(groupEntity);
468 } catch (Exception ex) {
469 LOG.error("removeSNATFromDPN : Failed to remove group entity {}", groupEntity, ex);
472 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routerName {}",
475 naptSwitchHA.removeSnatFlowsInOldNaptSwitch(routerName, routerId, naptSwitch,
476 externalIpLabel, confTx);
477 //remove table 26 flow ppointing to table46
478 FlowEntity flowEntity = null;
480 flowEntity = naptSwitchHA.buildSnatFlowEntityForNaptSwitch(dpnId, routerName, routerVpnId,
481 NatConstants.DEL_FLOW);
482 if (flowEntity == null) {
483 LOG.error("removeSNATFromDPN : Failed to populate flowentity for router {} with dpnId {}",
487 LOG.debug("removeSNATFromDPN : Removing default SNAT miss entry flow entity for router {} with "
488 + "dpnId {} in napt switch {}", routerName, dpnId, naptSwitch);
489 mdsalManager.removeFlow(confTx, flowEntity);
491 } catch (Exception ex) {
492 LOG.error("removeSNATFromDPN : Failed to remove default SNAT miss entry flow entity {}",
496 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routername {}",
499 //best effort to check IntExt model
500 naptSwitchHA.bestEffortDeletion(routerId, routerName, externalIpLabel, confTx);
502 } catch (InterruptedException | ExecutionException e) {
503 LOG.error("removeSNATFromDPN : Exception while handling naptSwitch down for router {}", routerName, e);
507 private void installDefaultNatRouteForRouterExternalSubnets(BigInteger dpnId, Collection<Uuid> externalSubnetIds) {
508 if (externalSubnetIds == null) {
509 LOG.error("installDefaultNatRouteForRouterExternalSubnets : No external subnets for router");
513 for (Uuid subnetId : externalSubnetIds) {
514 long vpnIdForSubnet = NatUtil.getExternalSubnetVpnId(dataBroker, subnetId);
515 if (vpnIdForSubnet != NatConstants.INVALID_ID) {
516 LOG.info("installDefaultNatRouteForRouterExternalSubnets : Installing default routes in FIB on dpn {} "
517 + "for subnetId {} with vpnId {}", dpnId, subnetId, vpnIdForSubnet);
518 snatDefaultRouteProgrammer.installDefNATRouteInDPN(dpnId, vpnIdForSubnet, subnetId.getValue());
520 LOG.debug("installDefaultNatRouteForRouterExternalSubnets : No vpnID for subnet {} found", subnetId);