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 com.google.common.base.Optional;
11 import com.google.common.util.concurrent.ListenableFuture;
13 import java.math.BigInteger;
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.Collections;
17 import java.util.List;
19 import javax.annotation.PostConstruct;
20 import javax.inject.Inject;
21 import javax.inject.Singleton;
23 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
24 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
25 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
26 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
27 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
28 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
29 import org.opendaylight.genius.mdsalutil.BucketInfo;
30 import org.opendaylight.genius.mdsalutil.FlowEntity;
31 import org.opendaylight.genius.mdsalutil.GroupEntity;
32 import org.opendaylight.genius.mdsalutil.MDSALUtil;
33 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
34 import org.opendaylight.netvirt.elanmanager.api.IElanService;
35 import org.opendaylight.netvirt.natservice.api.SnatServiceManager;
36 import org.opendaylight.netvirt.neutronvpn.interfaces.INeutronVpnManager;
37 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.NeutronRouterDpns;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnList;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesList;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.config.rev170206.NatserviceConfig;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.config.rev170206.NatserviceConfig.NatMode;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
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>
58 implements AutoCloseable {
60 private static final Logger LOG = LoggerFactory.getLogger(RouterDpnChangeListener.class);
61 private final DataBroker dataBroker;
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 IElanService elanManager;
69 private SnatServiceManager natServiceManager;
70 private NatMode natMode = NatMode.Controller;
73 public RouterDpnChangeListener(final DataBroker dataBroker, final IMdsalApiManager mdsalManager,
74 final SNATDefaultRouteProgrammer snatDefaultRouteProgrammer,
75 final NaptSwitchHA naptSwitchHA,
76 final IdManagerService idManager,
77 final ExternalNetworkGroupInstaller extNetGroupInstaller,
78 final INeutronVpnManager nvpnManager,
79 final SnatServiceManager natServiceManager,
80 final NatserviceConfig config,
81 final IElanService elanManager) {
82 super(DpnVpninterfacesList.class, RouterDpnChangeListener.class);
83 this.dataBroker = dataBroker;
84 this.mdsalManager = mdsalManager;
85 this.snatDefaultRouteProgrammer = snatDefaultRouteProgrammer;
86 this.naptSwitchHA = naptSwitchHA;
87 this.idManager = idManager;
88 this.extNetGroupInstaller = extNetGroupInstaller;
89 this.nvpnManager = nvpnManager;
90 this.elanManager = elanManager;
91 this.natServiceManager = natServiceManager;
93 this.natMode = config.getNatMode();
100 LOG.info("{} init", getClass().getSimpleName());
101 registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
105 protected RouterDpnChangeListener getDataTreeChangeListener() {
106 return RouterDpnChangeListener.this;
110 protected InstanceIdentifier<DpnVpninterfacesList> getWildCardPath() {
111 return InstanceIdentifier.create(NeutronRouterDpns.class).child(RouterDpnList.class)
112 .child(DpnVpninterfacesList.class);
116 protected void add(final InstanceIdentifier<DpnVpninterfacesList> identifier, final DpnVpninterfacesList dpnInfo) {
117 LOG.trace("add : key: {}, value: {}", dpnInfo.getKey(), dpnInfo);
118 final String routerId = identifier.firstKeyOf(RouterDpnList.class).getRouterId();
119 BigInteger dpnId = dpnInfo.getDpnId();
120 //check router is associated to external network
121 InstanceIdentifier<Routers> id = NatUtil.buildRouterIdentifier(routerId);
122 Optional<Routers> routerData =
123 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
124 LogicalDatastoreType.CONFIGURATION, id);
125 if (routerData.isPresent()) {
126 Routers router = routerData.get();
127 Uuid networkId = router.getNetworkId();
128 if (networkId != null) {
129 if (natMode == NatMode.Conntrack) {
130 BigInteger naptSwitch = NatUtil.getPrimaryNaptfromRouterName(dataBroker, router.getRouterName());
131 if (naptSwitch == null || naptSwitch.equals(BigInteger.ZERO)) {
132 LOG.warn("add : NAPT switch is not selected.");
135 //If it is a router port skip the notify.
136 for (Uuid subnetUuid :router.getSubnetIds()) {
138 Optional<Subnetmap> subnetMapEntry =
139 SingleTransactionDataBroker.syncReadOptional(dataBroker,
140 LogicalDatastoreType.CONFIGURATION, getSubnetMapIdentifier(subnetUuid));
141 if (subnetMapEntry.isPresent()) {
142 String routerPortUuid = subnetMapEntry.get().getRouterInterfacePortId().getValue();
143 List<RouterInterfaces> routerInterfaces = dpnInfo.getRouterInterfaces();
144 for (RouterInterfaces routerInterface : routerInterfaces) {
145 if (routerPortUuid.equals(routerInterface.getInterface())) {
150 } catch (ReadFailedException e) {
151 LOG.warn("add : The subnet map entry is not present.");
156 natServiceManager.notify(router, naptSwitch, dpnId,
157 SnatServiceManager.Action.SNAT_ROUTER_ENBL);
159 WriteTransaction writeFlowInvTx = dataBroker.newWriteOnlyTransaction();
160 WriteTransaction removeFlowInvTx = dataBroker.newWriteOnlyTransaction();
161 LOG.debug("add : Router {} is associated with ext nw {}", routerId, networkId);
162 Uuid vpnName = NatUtil.getVpnForRouter(dataBroker, routerId);
164 if (vpnName == null) {
165 LOG.debug("add : Internal vpn associated to router {}", routerId);
166 vpnId = NatUtil.getVpnId(dataBroker, routerId);
167 if (vpnId == NatConstants.INVALID_ID) {
168 LOG.error("add : Invalid vpnId returned for routerName {}", routerId);
171 LOG.debug("add : Retrieved vpnId {} for router {}", vpnId, routerId);
172 //Install default entry in FIB to SNAT table
173 LOG.info("add : Installing default route in FIB on dpn {} for router {} with vpn {}",
174 dpnId, routerId, vpnId);
175 installDefaultNatRouteForRouterExternalSubnets(dpnId,
176 NatUtil.getExternalSubnetIdsFromExternalIps(router.getExternalIps()));
177 snatDefaultRouteProgrammer.installDefNATRouteInDPN(dpnId, vpnId, writeFlowInvTx);
179 LOG.debug("add : External BGP vpn associated to router {}", routerId);
180 vpnId = NatUtil.getVpnId(dataBroker, vpnName.getValue());
181 if (vpnId == NatConstants.INVALID_ID) {
182 LOG.error("add : Invalid vpnId returned for routerName {}", routerId);
185 Long routId = NatUtil.getVpnId(dataBroker, routerId);
186 if (routId == NatConstants.INVALID_ID) {
187 LOG.error("add : Invalid routId returned for routerName {}", routerId);
190 LOG.debug("add : Retrieved vpnId {} for router {}", vpnId, routerId);
191 //Install default entry in FIB to SNAT table
192 LOG.debug("add : Installing default route in FIB on dpn {} for routerId {} with vpnId {}...",
193 dpnId, routerId, vpnId);
194 installDefaultNatRouteForRouterExternalSubnets(dpnId,
195 NatUtil.getExternalSubnetIdsFromExternalIps(router.getExternalIps()));
196 snatDefaultRouteProgrammer.installDefNATRouteInDPN(dpnId, vpnId, routId, writeFlowInvTx);
198 extNetGroupInstaller.installExtNetGroupEntries(networkId, dpnId);
200 if (router.isEnableSnat()) {
201 LOG.info("add : SNAT enabled for router {}", routerId);
202 handleSNATForDPN(dpnId, routerId, vpnId, writeFlowInvTx, removeFlowInvTx);
204 LOG.info("add : SNAT is not enabled for router {} to handle addDPN event {}", routerId, dpnId);
206 List<ListenableFuture<Void>> futures = new ArrayList<>();
207 futures.add(NatUtil.waitForTransactionToComplete(writeFlowInvTx));
208 futures.add(NatUtil.waitForTransactionToComplete(removeFlowInvTx));
209 } // end of controller based SNAT
212 LOG.debug("add : Router {} is not associated with External network", routerId);
217 protected void remove(InstanceIdentifier<DpnVpninterfacesList> identifier, DpnVpninterfacesList dpnInfo) {
218 LOG.trace("remove : key: {}, value: {}", dpnInfo.getKey(), dpnInfo);
219 final String routerId = identifier.firstKeyOf(RouterDpnList.class).getRouterId();
220 BigInteger dpnId = dpnInfo.getDpnId();
221 //check router is associated to external network
222 InstanceIdentifier<Routers> id = NatUtil.buildRouterIdentifier(routerId);
223 Optional<Routers> routerData =
224 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
225 LogicalDatastoreType.CONFIGURATION, id);
226 if (routerData.isPresent()) {
227 Routers router = routerData.get();
228 Uuid networkId = router.getNetworkId();
229 if (networkId != null) {
230 if (natMode == NatMode.Conntrack) {
231 BigInteger naptSwitch = NatUtil.getPrimaryNaptfromRouterName(dataBroker, router.getRouterName());
232 if (naptSwitch == null || naptSwitch.equals(BigInteger.ZERO)) {
233 LOG.warn("remove : NAPT switch is not selected.");
236 natServiceManager.notify(router, naptSwitch, dpnId,
237 SnatServiceManager.Action.SNAT_ROUTER_DISBL);
239 WriteTransaction removeFlowInvTx = dataBroker.newWriteOnlyTransaction();
240 LOG.debug("remove : Router {} is associated with ext nw {}", routerId, networkId);
241 Uuid vpnName = NatUtil.getVpnForRouter(dataBroker, routerId);
243 if (vpnName == null) {
244 LOG.debug("remove : Internal vpn associated to router {}", routerId);
245 vpnId = NatUtil.getVpnId(dataBroker, routerId);
246 if (vpnId == NatConstants.INVALID_ID) {
247 LOG.error("remove : Invalid vpnId returned for routerName {}", routerId);
250 LOG.debug("remove : Retrieved vpnId {} for router {}", vpnId, routerId);
251 //Remove default entry in FIB
252 LOG.debug("remove : Removing default route in FIB on dpn {} for vpn {} ...", dpnId, vpnName);
253 snatDefaultRouteProgrammer.removeDefNATRouteInDPN(dpnId, vpnId, removeFlowInvTx);
255 LOG.debug("remove : External vpn associated to router {}", routerId);
256 vpnId = NatUtil.getVpnId(dataBroker, vpnName.getValue());
257 if (vpnId == NatConstants.INVALID_ID) {
258 LOG.error("remove : Invalid vpnId returned for routerName {}", routerId);
261 Long routId = NatUtil.getVpnId(dataBroker, routerId);
262 if (routId == NatConstants.INVALID_ID) {
263 LOG.error("remove : Invalid routId returned for routerName {}", routerId);
266 LOG.debug("remove : Retrieved vpnId {} for router {}", vpnId, routerId);
267 //Remove default entry in FIB
268 LOG.debug("remove : Removing default route in FIB on dpn {} for vpn {} ...", dpnId, vpnName);
269 snatDefaultRouteProgrammer.removeDefNATRouteInDPN(dpnId, vpnId, routId, removeFlowInvTx);
272 if (router.isEnableSnat()) {
273 LOG.info("remove : SNAT enabled for router {}", routerId);
274 removeSNATFromDPN(dpnId, routerId, vpnId, removeFlowInvTx);
276 LOG.info("remove : SNAT is not enabled for router {} to handle removeDPN event {}",
279 List<ListenableFuture<Void>> futures = new ArrayList<>();
280 futures.add(NatUtil.waitForTransactionToComplete(removeFlowInvTx));
281 } // end of controller based SNAT
287 protected void update(InstanceIdentifier<DpnVpninterfacesList> identifier, DpnVpninterfacesList original,
288 DpnVpninterfacesList update) {
289 LOG.trace("Update key: {}, original: {}, update: {}", update.getKey(), original, update);
292 // TODO Clean up the exception handling
293 @SuppressWarnings("checkstyle:IllegalCatch")
294 void handleSNATForDPN(BigInteger dpnId, String routerName, Long routerVpnId, WriteTransaction writeFlowInvTx,
295 WriteTransaction removeFlowInvTx) {
296 //Check if primary and secondary switch are selected, If not select the role
297 //Install select group to NAPT switch
298 //Install default miss entry to NAPT switch
299 BigInteger naptSwitch;
301 Long routerId = NatUtil.getVpnId(dataBroker, routerName);
302 if (routerId == NatConstants.INVALID_ID) {
303 LOG.error("handleSNATForDPN : Invalid routerId returned for routerName {}", routerName);
306 BigInteger naptId = NatUtil.getPrimaryNaptfromRouterName(dataBroker, routerName);
307 if (naptId == null || naptId.equals(BigInteger.ZERO) || !naptSwitchHA.getSwitchStatus(naptId)) {
308 LOG.debug("handleSNATForDPN : No NaptSwitch is selected for router {}", routerName);
310 boolean naptstatus = naptSwitchHA.updateNaptSwitch(routerName, naptSwitch);
312 LOG.error("handleSNATForDPN : Failed to update newNaptSwitch {} for routername {}",
313 naptSwitch, routerName);
316 LOG.debug("handleSNATForDPN : Switch {} is elected as NaptSwitch for router {}", dpnId, routerName);
318 // When NAPT switch is elected during first VM comes up for the given Router
319 if (elanManager.isOpenStackVniSemanticsEnforced()) {
320 NatOverVxlanUtil.validateAndCreateVxlanVniPool(dataBroker, nvpnManager,
321 idManager, NatConstants.ODL_VNI_POOL_NAME);
324 Routers extRouters = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
325 if (extRouters != null) {
326 NatUtil.createRouterIdsConfigDS(dataBroker, routerName);
327 naptSwitchHA.subnetRegisterMapping(extRouters, routerId);
330 naptSwitchHA.installSnatFlows(routerName, routerId, naptSwitch, routerVpnId, writeFlowInvTx);
332 // Install miss entry (table 26) pointing to table 46
333 FlowEntity flowEntity = naptSwitchHA.buildSnatFlowEntityForNaptSwitch(dpnId, routerName,
334 routerVpnId, NatConstants.ADD_FLOW);
335 if (flowEntity == null) {
336 LOG.error("handleSNATForDPN : Failed to populate flowentity for router {} with dpnId {}",
340 LOG.debug("handleSNATForDPN : Successfully installed flow for dpnId {} router {}", dpnId, routerName);
341 mdsalManager.addFlowToTx(flowEntity, writeFlowInvTx);
342 //Removing primary flows from old napt switch
343 if (naptId != null && !naptId.equals(BigInteger.ZERO)) {
344 LOG.debug("handleSNATForDPN : Removing primary flows from old napt switch {} for router {}",
346 naptSwitchHA.removeSnatFlowsInOldNaptSwitch(routerName, naptId, null, removeFlowInvTx);
348 } else if (naptId.equals(dpnId)) {
349 LOG.debug("handleSNATForDPN : NaptSwitch {} gone down during cluster reboot came alive", naptId);
352 LOG.debug("handleSNATForDPN : Napt switch with Id {} is already elected for router {}",
356 List<BucketInfo> bucketInfo = naptSwitchHA.handleGroupInNeighborSwitches(dpnId,
357 routerName, naptSwitch);
358 if (bucketInfo == null) {
359 LOG.error("handleSNATForDPN:Failed to populate bucketInfo for dpnId {},routername {},naptSwitch {}",
360 dpnId, routerName, naptSwitch);
363 naptSwitchHA.installSnatGroupEntry(dpnId, bucketInfo, routerName);
365 // Install miss entry (table 26) pointing to group
366 long groupId = NatUtil.createGroupId(NatUtil.getGroupIdKey(routerName), idManager);
367 FlowEntity flowEntity =
368 naptSwitchHA.buildSnatFlowEntity(dpnId, routerName, groupId,
369 routerVpnId, NatConstants.ADD_FLOW);
370 if (flowEntity == null) {
371 LOG.error("handleSNATForDPN : Failed to populate flowentity for router {} with dpnId {} groupId {}",
372 routerName, dpnId, groupId);
375 LOG.debug("handleSNATForDPN : Successfully installed flow for dpnId {} router {} group {}",
376 dpnId, routerName, groupId);
377 mdsalManager.addFlowToTx(flowEntity, writeFlowInvTx);
380 } catch (Exception ex) {
381 LOG.error("handleSNATForDPN : Exception in handleSNATForDPN", ex);
385 // TODO Clean up the exception handling
386 @SuppressWarnings("checkstyle:IllegalCatch")
387 void removeSNATFromDPN(BigInteger dpnId, String routerName, long routerVpnId, WriteTransaction removeFlowInvTx) {
388 //irrespective of naptswitch or non-naptswitch, SNAT default miss entry need to be removed
389 //remove miss entry to NAPT switch
390 //if naptswitch elect new switch and install Snat flows and remove those flows in oldnaptswitch
392 Long routerId = NatUtil.getVpnId(dataBroker, routerName);
393 if (routerId == NatConstants.INVALID_ID) {
394 LOG.error("removeSNATFromDPN : Invalid routerId returned for routerName {}", routerName);
397 Collection<String> externalIpCache = NatUtil.getExternalIpsForRouter(dataBroker, routerId);
398 ProviderTypes extNwProvType = NatEvpnUtil.getExtNwProvTypeFromRouterName(dataBroker, routerName);
399 if (extNwProvType == null) {
402 //Get the external IP labels other than VXLAN provider type. Since label is not applicable for VXLAN
403 Map<String, Long> externalIpLabel;
404 if (extNwProvType == ProviderTypes.VXLAN) {
405 externalIpLabel = null;
407 externalIpLabel = NatUtil.getExternalIpsLabelForRouter(dataBroker, routerId);
409 BigInteger naptSwitch = NatUtil.getPrimaryNaptfromRouterName(dataBroker, routerName);
410 if (naptSwitch == null || naptSwitch.equals(BigInteger.ZERO)) {
411 LOG.error("removeSNATFromDPN : No naptSwitch is selected for router {}", routerName);
416 naptSwitchHA.isNaptSwitchDown(routerName, dpnId, naptSwitch, routerVpnId, externalIpCache,
419 LOG.debug("removeSNATFromDPN: Switch with DpnId {} is not naptSwitch for router {}",
421 long groupId = NatUtil.createGroupId(NatUtil.getGroupIdKey(routerName), idManager);
422 FlowEntity flowEntity = null;
424 flowEntity = naptSwitchHA.buildSnatFlowEntity(dpnId, routerName, groupId, routerVpnId,
425 NatConstants.DEL_FLOW);
426 if (flowEntity == null) {
427 LOG.error("removeSNATFromDPN : Failed to populate flowentity for router:{} "
428 + "with dpnId:{} groupId:{}", routerName, dpnId, groupId);
431 LOG.debug("removeSNATFromDPN : Removing default SNAT miss entry flow entity {}", flowEntity);
432 mdsalManager.removeFlowToTx(flowEntity, removeFlowInvTx);
434 } catch (Exception ex) {
435 LOG.error("removeSNATFromDPN : Failed to remove default SNAT miss entry flow entity {}",
439 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routername {}",
443 GroupEntity groupEntity = null;
445 groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, routerName,
446 GroupTypes.GroupAll, Collections.emptyList() /*listBucketInfo*/);
447 LOG.info("removeSNATFromDPN : Removing NAPT GroupEntity:{}", groupEntity);
448 mdsalManager.removeGroup(groupEntity);
449 } catch (Exception ex) {
450 LOG.error("removeSNATFromDPN : Failed to remove group entity {}", groupEntity, ex);
453 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routerName {}",
456 naptSwitchHA.removeSnatFlowsInOldNaptSwitch(routerName, naptSwitch, externalIpLabel, removeFlowInvTx);
457 //remove table 26 flow ppointing to table46
458 FlowEntity flowEntity = null;
460 flowEntity = naptSwitchHA.buildSnatFlowEntityForNaptSwitch(dpnId, routerName, routerVpnId,
461 NatConstants.DEL_FLOW);
462 if (flowEntity == null) {
463 LOG.error("removeSNATFromDPN : Failed to populate flowentity for router {} with dpnId {}",
467 LOG.debug("removeSNATFromDPN : Removing default SNAT miss entry flow entity for router {} with "
468 + "dpnId {} in napt switch {}", routerName, dpnId, naptSwitch);
469 mdsalManager.removeFlowToTx(flowEntity, removeFlowInvTx);
471 } catch (Exception ex) {
472 LOG.error("removeSNATFromDPN : Failed to remove default SNAT miss entry flow entity {}",
476 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routername {}",
479 //best effort to check IntExt model
480 naptSwitchHA.bestEffortDeletion(routerId, routerName, externalIpLabel, removeFlowInvTx);
482 } catch (Exception ex) {
483 LOG.error("removeSNATFromDPN : Exception while handling naptSwitch down for router {}", routerName, ex);
487 private void installDefaultNatRouteForRouterExternalSubnets(BigInteger dpnId, Collection<Uuid> externalSubnetIds) {
488 if (externalSubnetIds == null) {
489 LOG.error("installDefaultNatRouteForRouterExternalSubnets : No external subnets for router");
493 for (Uuid subnetId : externalSubnetIds) {
494 long vpnIdForSubnet = NatUtil.getExternalSubnetVpnId(dataBroker, subnetId);
495 if (vpnIdForSubnet != NatConstants.INVALID_ID) {
496 LOG.info("installDefaultNatRouteForRouterExternalSubnets : Installing default routes in FIB on dpn {} "
497 + "for subnetId {} with vpnId {}", dpnId, subnetId, vpnIdForSubnet);
498 snatDefaultRouteProgrammer.installDefNATRouteInDPN(dpnId, vpnIdForSubnet, subnetId.getValue(),
501 LOG.debug("installDefaultNatRouteForRouterExternalSubnets : No vpnID for subnet {} found", subnetId);
506 private InstanceIdentifier<Subnetmap> getSubnetMapIdentifier(Uuid subnetId) {
507 return InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class,
508 new SubnetmapKey(subnetId)).build();