* @return success/failure
*/
BigInteger getCentralizedSwitch(String routerName);
-
- /**
- * Adds a switch to the scheduler pool.
- * @param dpnId the switch id.
- * @return success/failure
- */
- boolean addSwitch(BigInteger dpnId);
-
- /**
- * Removes a switch from the scheduler pool.
- * @param dpnId the switch id.
- * @return success/failure
- */
- boolean removeSwitch(BigInteger dpnId);
-
- /**
- * Check whether the switch has external bridge mappings.
- * @param dpnId the switch id.
- * @param providerNet the provider network.
- * @return whether connected to provider network or not.
- */
- boolean isSwitchConnectedToExternal(BigInteger dpnId, String providerNet);
-
}
--- /dev/null
+/*
+ * Copyright (c) 2018 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netvirt.natservice.api;
+
+import java.math.BigInteger;
+import java.util.Map;
+import java.util.Set;
+
+public interface NatSwitchCache {
+
+ /**
+ * Adds a switch to the scheduler pool.
+ * @param dpnId the switch id.
+ */
+ void addSwitch(BigInteger dpnId);
+
+ /**
+ * Removes a switch from the scheduler pool.
+ * @param dpnId the switch id.
+ */
+ void removeSwitch(BigInteger dpnId);
+
+ /**
+ * Check whether the switch has external bridge mappings.
+ * @param dpnId the switch id.
+ * @param providerNet the provider network.
+ * @return whether connected to provider network or not.
+ */
+ boolean isSwitchConnectedToExternal(BigInteger dpnId, String providerNet);
+
+ /**
+ * Return the switches which has external bridge mappings.
+ * @param providerNet the provider network.
+ * @return the set of switches which has the mapping
+ */
+ Set<BigInteger> getSwitchesConnectedToExternal(String providerNet);
+
+ /**
+ * Return the switches map with weight.
+ * @return the map of switches
+ */
+ Map<BigInteger,SwitchInfo> getSwitches();
+
+ /**
+ * Register for switch added notification.
+ * @param centralizedSwitchCacheListener the instance of a listener
+ */
+ void register(NatSwitchCacheListener centralizedSwitchCacheListener);
+
+ /**
+ * Register for switch removed notification.
+ * @param centralizedSwitchCacheListener the instance of a listener
+ */
+ void deregister(NatSwitchCacheListener centralizedSwitchCacheListener);
+
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netvirt.natservice.api;
+
+public interface NatSwitchCacheListener {
+
+ /**
+ * Switch is added.
+ * @param switchInfo the switch details.
+ */
+ void switchAddedToCache(SwitchInfo switchInfo);
+
+ /**
+ * Switch is removed.
+ * @param switchInfo the switch details.
+ */
+ void switchRemovedFromCache(SwitchInfo switchInfo);
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netvirt.natservice.api;
+
+import java.math.BigInteger;
+import java.util.Set;
+
+public final class SwitchInfo {
+
+ BigInteger dpnId;
+
+ Set<String> providerNets;
+
+ public BigInteger getDpnId() {
+ return dpnId;
+ }
+
+ public void setDpnId(BigInteger dpnId) {
+ this.dpnId = dpnId;
+ }
+
+ public Set<String> getProviderNets() {
+ return providerNets;
+ }
+
+ public void setProviderNets(Set<String> providerNets) {
+ this.providerNets = providerNets;
+ }
+
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netvirt.natservice.ha;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.netvirt.natservice.api.NatSwitchCache;
+import org.opendaylight.netvirt.natservice.api.NatSwitchCacheListener;
+import org.opendaylight.netvirt.natservice.api.SwitchInfo;
+import org.opendaylight.netvirt.natservice.internal.NatUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+public class NatSwitchCacheImpl implements NatSwitchCache {
+
+ private static final Logger LOG = LoggerFactory.getLogger(NatSwitchCacheImpl.class);
+ ConcurrentMap<BigInteger,SwitchInfo> switchMap = new ConcurrentHashMap<>();
+
+ private final List<NatSwitchCacheListener> centralizedSwitchCacheListenerList =
+ new ArrayList<NatSwitchCacheListener>();
+ private final DataBroker dataBroker;
+
+ @Inject
+ public NatSwitchCacheImpl(final DataBroker dataBroker) {
+ this.dataBroker = dataBroker;
+ }
+
+ @Override
+ public void addSwitch(BigInteger dpnId) {
+ LOG.info("addSwitch: Retrieving the provider config for {}", dpnId);
+ Map<String, String> providerMappingsMap = NatUtil.getOpenvswitchOtherConfigMap(dpnId, dataBroker);
+ SwitchInfo switchInfo = new SwitchInfo();
+ switchInfo.setDpnId(dpnId);
+ switchInfo.setProviderNets(providerMappingsMap.keySet());
+ switchMap.put(dpnId, switchInfo);
+ for (NatSwitchCacheListener centralizedSwitchCacheListener : centralizedSwitchCacheListenerList) {
+ centralizedSwitchCacheListener.switchAddedToCache(switchInfo);
+ }
+ }
+
+ @Override
+ public void removeSwitch(BigInteger dpnId) {
+ LOG.info("removeSwitch: Removing {} dpnId to switchWeightsMap", dpnId);
+ SwitchInfo switchInfo = switchMap.get(dpnId);
+ for (NatSwitchCacheListener centralizedSwitchCacheListener : centralizedSwitchCacheListenerList) {
+ centralizedSwitchCacheListener.switchRemovedFromCache(switchInfo);
+ }
+ }
+
+ @Override
+ public boolean isSwitchConnectedToExternal(BigInteger dpnId, String providerNet) {
+ SwitchInfo switchInfo = switchMap.get(dpnId);
+ if (switchInfo != null) {
+ return switchInfo.getProviderNets().contains(providerNet);
+ }
+ return false;
+ }
+
+ @Override
+ public Set<BigInteger> getSwitchesConnectedToExternal(String providerNet) {
+ Set<BigInteger> switches = new HashSet<>();
+ for (Map.Entry<BigInteger,SwitchInfo> switchesEntrySet : switchMap.entrySet()) {
+ Set<String> providerNetSet = switchesEntrySet.getValue().getProviderNets();
+ if (providerNetSet != null && providerNetSet.contains(providerNet)) {
+ switches.add(switchesEntrySet.getKey());
+ }
+ }
+ return switches;
+ }
+
+ public void register(NatSwitchCacheListener centralizedSwitchCacheListener) {
+ if (centralizedSwitchCacheListener != null) {
+ centralizedSwitchCacheListenerList.add(centralizedSwitchCacheListener);
+ }
+ }
+
+ public void deregister(NatSwitchCacheListener centralizedSwitchCacheListener) {
+ if (centralizedSwitchCacheListener != null) {
+ centralizedSwitchCacheListenerList.remove(centralizedSwitchCacheListener);
+ }
+ }
+
+ @Override
+ public Map<BigInteger,SwitchInfo> getSwitches() {
+ return switchMap;
+ }
+}
import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.genius.mdsalutil.MDSALUtil;
-import org.opendaylight.netvirt.natservice.api.CentralizedSwitchScheduler;
+import org.opendaylight.netvirt.natservice.api.NatSwitchCache;
import org.opendaylight.serviceutils.tools.mdsal.listener.AbstractClusteredAsyncDataTreeChangeListener;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
@Singleton
public class SnatNodeEventListener extends AbstractClusteredAsyncDataTreeChangeListener<Node> {
private static final Logger LOG = LoggerFactory.getLogger(SnatNodeEventListener.class);
- private final CentralizedSwitchScheduler centralizedSwitchScheduler;
+ private final NatSwitchCache centralizedSwitchCache;
@Inject
public SnatNodeEventListener(final DataBroker dataBroker,
- final CentralizedSwitchScheduler centralizedSwitchScheduler) {
+ final NatSwitchCache centralizedSwitchCache) {
super(dataBroker,new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier
.create(Nodes.class).child(Node.class)),
Executors.newSingleThreadExecutor());
- this.centralizedSwitchScheduler = centralizedSwitchScheduler;
+ this.centralizedSwitchCache = centralizedSwitchCache;
}
@Override
NodeKey nodeKey = dataObjectModification.key();
BigInteger dpnId = MDSALUtil.getDpnIdFromNodeName(nodeKey.getId());
LOG.info("Dpn removed {}", dpnId);
- centralizedSwitchScheduler.removeSwitch(dpnId);
+ centralizedSwitchCache.removeSwitch(dpnId);
}
@Override
NodeKey nodeKey = dataObjectModification.key();
BigInteger dpnId = MDSALUtil.getDpnIdFromNodeName(nodeKey.getId());
LOG.info("Dpn added {}", dpnId);
- centralizedSwitchScheduler.addSwitch(dpnId);
+ centralizedSwitchCache.addSwitch(dpnId);
}
}
import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
import org.opendaylight.netvirt.natservice.api.CentralizedSwitchScheduler;
+import org.opendaylight.netvirt.natservice.api.NatSwitchCache;
+import org.opendaylight.netvirt.natservice.api.NatSwitchCacheListener;
+import org.opendaylight.netvirt.natservice.api.SwitchInfo;
import org.opendaylight.netvirt.natservice.internal.NatUtil;
import org.opendaylight.netvirt.vpnmanager.api.IVpnFootprintService;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
import org.slf4j.LoggerFactory;
@Singleton
-public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchScheduler {
+public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchScheduler, NatSwitchCacheListener {
private static final Logger LOG = LoggerFactory.getLogger(WeightedCentralizedSwitchScheduler.class);
private static final Integer INITIAL_SWITCH_WEIGHT = Integer.valueOf(0);
private final NatserviceConfig.NatMode natMode;
@Inject
- public WeightedCentralizedSwitchScheduler(DataBroker dataBroker, OdlInterfaceRpcService interfaceManager,
- IVpnFootprintService vpnFootprintService, final NatserviceConfig config) {
+ public WeightedCentralizedSwitchScheduler(final DataBroker dataBroker,
+ final OdlInterfaceRpcService interfaceManager,
+ final IVpnFootprintService vpnFootprintService, final NatserviceConfig config,
+ final NatSwitchCache natSwitchCache) {
this.dataBroker = dataBroker;
this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
this.interfaceManager = interfaceManager;
} else {
this.natMode = NatserviceConfig.NatMode.Controller;
}
+ natSwitchCache.register(this);
}
@Override
}
}
-
-
private void deleteFromDpnMaps(String routerName, List<Uuid> deletedSubnetIds, BigInteger primarySwitchId) {
if (deletedSubnetIds == null || deletedSubnetIds.isEmpty()) {
LOG.debug("deleteFromDpnMaps no subnets associated with {}", routerName);
}
@Override
- public boolean addSwitch(BigInteger dpnId) {
- /* Initialize the switch in the map with weight 0 */
- LOG.info("addSwitch: Retrieving the provider config for {}", dpnId);
+ public void switchAddedToCache(SwitchInfo switchInfo) {
boolean scheduleRouters = (providerSwitchWeightsMap.size() == 0) ? true : false;
- Map<String, String> providerMappingsMap = NatUtil.getOpenvswitchOtherConfigMap(dpnId, dataBroker);
- for (String providerNet : providerMappingsMap.keySet()) {
+ for (String providerNet : switchInfo.getProviderNets()) {
Map<BigInteger,Integer> switchWeightMap = providerSwitchWeightsMap.get(providerNet);
if (providerSwitchWeightsMap.get(providerNet) == null) {
switchWeightMap = new ConcurrentHashMap<>();
providerSwitchWeightsMap.put(providerNet, switchWeightMap);
}
- LOG.info("addSwitch: Adding {} dpnId with provider mapping {} to switchWeightsMap", dpnId, providerNet);
- switchWeightMap.put(dpnId, INITIAL_SWITCH_WEIGHT);
+ LOG.info("addSwitch: Adding {} dpnId with provider mapping {} to switchWeightsMap",
+ switchInfo.getDpnId(), providerNet);
+ switchWeightMap.put(switchInfo.getDpnId(), INITIAL_SWITCH_WEIGHT);
}
if (natMode == NatserviceConfig.NatMode.Conntrack && scheduleRouters) {
Optional<ExtRouters> optRouters;
LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(ExtRouters.class));
} catch (ReadFailedException e) {
LOG.error("addSwitch: Error reading external routers", e);
- return false;
+ return;
}
if (optRouters.isPresent()) {
}
}
}
- return true;
+ return;
}
private boolean isPrimarySwitchAllocatedForRouter(String routerName) {
}
@Override
- public boolean removeSwitch(BigInteger dpnId) {
+ public void switchRemovedFromCache(SwitchInfo switchInfo) {
+ BigInteger dpnId = switchInfo.getDpnId();
LOG.info("removeSwitch: Removing {} dpnId to switchWeightsMap", dpnId);
for (Map.Entry<String,Map<BigInteger,Integer>> providerNet : providerSwitchWeightsMap.entrySet()) {
Map<BigInteger,Integer> switchWeightMap = providerNet.getValue();
}
switchWeightMap.remove(dpnId);
}
- return true;
+ return;
}
private NaptSwitches getNaptSwitches() {
}
}
- @Override
- public boolean isSwitchConnectedToExternal(BigInteger dpnId, String providerNet) {
- Map<BigInteger,Integer> switchWeightMap = providerSwitchWeightsMap.get(providerNet);
- if (switchWeightMap != null) {
- return switchWeightMap.containsKey(dpnId);
- }
- return false;
- }
-
@Nullable
- public static List<Uuid> getUpdatedSubnetIds(List<Uuid> updatedSubnetIds, List<Uuid> currentSubnetIds) {
+ private static List<Uuid> getUpdatedSubnetIds(List<Uuid> updatedSubnetIds, List<Uuid> currentSubnetIds) {
if (updatedSubnetIds == null) {
return null;
}
package org.opendaylight.netvirt.natservice.internal;
import com.google.common.base.Optional;
-import java.util.List;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
-import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
-import org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar;
import org.opendaylight.genius.mdsalutil.NwConstants;
import org.opendaylight.netvirt.elanmanager.api.IElanService;
import org.opendaylight.netvirt.vpnmanager.api.IVpnManager;
-import org.opendaylight.serviceutils.upgrade.UpgradeState;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.Subnets;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
private final SNATDefaultRouteProgrammer snatDefaultRouteProgrammer;
private final IElanService elanService;
private final IVpnManager vpnManager;
- private final UpgradeState upgradeState;
- private final DataTreeEventCallbackRegistrar dataTreeEventCallbackRegistrar;
@Inject
public ExternalSubnetVpnInstanceListener(final DataBroker dataBroker,
final SNATDefaultRouteProgrammer snatDefaultRouteProgrammer,
- final IElanService elanService, final IVpnManager vpnManager,
- final UpgradeState upgradeState, DataTreeEventCallbackRegistrar dataTreeEventCallbackRegistrar) {
+ final IElanService elanService, final IVpnManager vpnManager) {
this.dataBroker = dataBroker;
this.snatDefaultRouteProgrammer = snatDefaultRouteProgrammer;
this.elanService = elanService;
this.vpnManager = vpnManager;
- this.upgradeState = upgradeState;
- this.dataTreeEventCallbackRegistrar = dataTreeEventCallbackRegistrar;
}
@Override
String vpnInstanceName = vpnInstance.getVpnInstanceName();
LOG.debug("addOrDelDefaultFibRouteToSNATFlow : VpnInstance {} for external subnet {}.",
vpnInstanceName, subnet);
- Long vpnId = vpnInstance.getVpnId();
-
- if (upgradeState.isUpgradeInProgress()) {
- LOG.info("Upgrade in process, checking for existence of VpnInstanceOpDataEntry's vpn->dpn list");
- InstanceIdentifier<VpnInstanceOpDataEntry> vpnOpDataIid =
- NatUtil.getVpnInstanceOpDataIdentifier(subnet.getExternalNetworkId().getValue());
-
- Optional<VpnInstanceOpDataEntry> networkVpnInstanceOp;
- try {
- networkVpnInstanceOp = SingleTransactionDataBroker.syncReadOptional(
- dataBroker, LogicalDatastoreType.OPERATIONAL, vpnOpDataIid);
- } catch (ReadFailedException e) {
- LOG.error("Exception while attempting to read VpnInstanceOpDataEntry", e);
- return;
- }
-
- List<VpnToDpnList> dpnListInVpn = null;
- if (networkVpnInstanceOp.isPresent()) {
- dpnListInVpn = networkVpnInstanceOp.get().getVpnToDpnList();
- }
-
- if (dpnListInVpn == null) {
- LOG.info("VpnInstanceOpDataEntry's vpn->dpn list not present, wait for it");
- dataTreeEventCallbackRegistrar.onAddOrUpdate(LogicalDatastoreType.OPERATIONAL, vpnOpDataIid,
- (beforeOpData, afterOpData) -> {
- LOG.info("VpnInstanceOpDataEntry added/updated {}", afterOpData);
- if (afterOpData.getVpnToDpnList() == null) {
- if (upgradeState.isUpgradeInProgress()) {
- return DataTreeEventCallbackRegistrar.NextAction.CALL_AGAIN;
- } else {
- return DataTreeEventCallbackRegistrar.NextAction.UNREGISTER;
- }
- }
- snatDefaultRouteProgrammer.addOrDelDefaultFibRouteToSNATForSubnet(subnet,
- subnet.getExternalNetworkId().getValue(), flowAction, vpnId);
- return DataTreeEventCallbackRegistrar.NextAction.UNREGISTER;
- });
- return;
- }
- LOG.info("VpnInstanceOpDataEntry's vpn->dpn list present, continue with regular scheduled programming");
-
- }
-
snatDefaultRouteProgrammer.addOrDelDefaultFibRouteToSNATForSubnet(subnet,
- subnet.getExternalNetworkId().getValue(), flowAction, vpnId);
+ subnet.getExternalNetworkId().getValue(), flowAction, vpnInstance.getVpnId());
}
@Override
import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
import org.opendaylight.netvirt.natservice.api.CentralizedSwitchScheduler;
+import org.opendaylight.netvirt.natservice.api.NatSwitchCache;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
private final SNATDefaultRouteProgrammer defaultRouteProgrammer;
private final JobCoordinator coordinator;
private final CentralizedSwitchScheduler centralizedSwitchScheduler;
+ private final NatSwitchCache natSwitchCache;
@Inject
public FloatingIPListener(final DataBroker dataBroker, final IMdsalApiManager mdsalManager,
final FloatingIPHandler floatingIPHandler,
final SNATDefaultRouteProgrammer snatDefaultRouteProgrammer,
final JobCoordinator coordinator,
- final CentralizedSwitchScheduler centralizedSwitchScheduler) {
+ final CentralizedSwitchScheduler centralizedSwitchScheduler,
+ final NatSwitchCache natSwitchCache) {
super(InternalToExternalPortMap.class, FloatingIPListener.class);
this.dataBroker = dataBroker;
this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
this.defaultRouteProgrammer = snatDefaultRouteProgrammer;
this.coordinator = coordinator;
this.centralizedSwitchScheduler = centralizedSwitchScheduler;
+ this.natSwitchCache = natSwitchCache;
}
@Override
// mappings) and then sent out on the external Network.
if (providerType == ProviderTypes.FLAT || providerType == ProviderTypes.VLAN) {
String providerNet = NatUtil.getElanInstancePhysicalNetwok(extNwId.getValue(), dataBroker);
- boolean isDpnConnected = centralizedSwitchScheduler.isSwitchConnectedToExternal(updatedDpnId, providerNet);
+ boolean isDpnConnected = natSwitchCache.isSwitchConnectedToExternal(updatedDpnId, providerNet);
if (!isDpnConnected) {
updatedDpnId = centralizedSwitchScheduler.getCentralizedSwitch(routerName);
}
--- /dev/null
+/*
+ * Copyright (c) 2018 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netvirt.natservice.internal;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.genius.mdsalutil.NwConstants;
+import org.opendaylight.netvirt.natservice.api.NatSwitchCache;
+import org.opendaylight.netvirt.natservice.api.NatSwitchCacheListener;
+import org.opendaylight.netvirt.natservice.api.SwitchInfo;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.config.rev170206.NatserviceConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalSubnets;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.Subnets;
+
+@Singleton
+public class NatSwitchCacheListenerImpl implements NatSwitchCacheListener {
+
+ private final DataBroker dataBroker;
+ private final SNATDefaultRouteProgrammer snatDefaultRouteProgrammer;
+
+ @Inject
+ public NatSwitchCacheListenerImpl(final DataBroker dataBroker,
+ final SNATDefaultRouteProgrammer snatDefaultRouteProgrammer, NatSwitchCache natSwitchCache,
+ final NatserviceConfig config) {
+ this.dataBroker = dataBroker;
+ this.snatDefaultRouteProgrammer = snatDefaultRouteProgrammer;
+ if (config != null && config.getNatMode().equals(NatserviceConfig.NatMode.Conntrack)) {
+ natSwitchCache.register(this);
+ }
+ }
+
+ public void switchAddedToCache(SwitchInfo switchInfo) {
+ ExternalSubnets externalSubnets = NatUtil.getExternalSubnets(dataBroker);
+ if (externalSubnets != null) {
+ for (Subnets externalSubnet : externalSubnets.getSubnets()) {
+ Uuid externalNetworkUuid = externalSubnet.getExternalNetworkId();
+ String providerNet = NatUtil.getElanInstancePhysicalNetwok(externalNetworkUuid.getValue(),
+ dataBroker);
+ if (switchInfo.getProviderNets().contains(providerNet)) {
+ long vpnid = NatUtil.getVpnId(dataBroker, externalNetworkUuid.getValue());
+ snatDefaultRouteProgrammer.addOrDelDefaultFibRouteToSNATForSubnetInDpn(externalSubnet,
+ externalNetworkUuid.getValue(), NwConstants.ADD_FLOW, vpnid, switchInfo.getDpnId());
+ }
+ }
+ }
+ }
+
+ public void switchRemovedFromCache(SwitchInfo switchInfo) {
+ /* Do Nothing */
+ }
+}
public static String getDefaultFibRouteToSNATForSubnetJobKey(String subnetName, BigInteger dpnId) {
return NatConstants.NAT_DJC_PREFIX + subnetName + dpnId;
}
+
+ public static ExternalSubnets getExternalSubnets(DataBroker dataBroker) {
+ InstanceIdentifier<ExternalSubnets> subnetsIdentifier =
+ InstanceIdentifier.builder(ExternalSubnets.class)
+ .build();
+ try {
+ Optional<ExternalSubnets> optionalExternalSubnets = SingleTransactionDataBroker
+ .syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
+ if (optionalExternalSubnets.isPresent()) {
+ return optionalExternalSubnets.get();
+ }
+ } catch (ReadFailedException e) {
+ LOG.error("Failed to read the subnets from the datastore.");
+ }
+ return null;
+
+ }
}
*/
package org.opendaylight.netvirt.natservice.internal;
-import com.google.common.base.Optional;
import java.math.BigInteger;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-
+import java.util.Set;
import java.util.concurrent.ExecutionException;
import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
import org.opendaylight.genius.infra.Datastore.Configuration;
import org.opendaylight.genius.infra.TypedReadWriteTransaction;
import org.opendaylight.genius.infra.TypedWriteTransaction;
import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
+import org.opendaylight.netvirt.natservice.api.NatSwitchCache;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.Subnets;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private final ExternalNetworkGroupInstaller extNetGroupInstaller;
private final NatServiceCounters natServiceCounters;
private final JobCoordinator jobCoordinator;
+ private final NatSwitchCache natSwitchCache;
@Inject
public SNATDefaultRouteProgrammer(final IMdsalApiManager mdsalManager, final DataBroker dataBroker,
final IdManagerService idManager, final ExternalNetworkGroupInstaller extNetGroupInstaller,
- NatServiceCounters natServiceCounters, final JobCoordinator jobCoordinator) {
+ NatServiceCounters natServiceCounters, final JobCoordinator jobCoordinator,
+ final NatSwitchCache natSwitchCache) {
this.mdsalManager = mdsalManager;
this.dataBroker = dataBroker;
this.idManager = idManager;
this.extNetGroupInstaller = extNetGroupInstaller;
this.natServiceCounters = natServiceCounters;
this.jobCoordinator = jobCoordinator;
+ this.natSwitchCache = natSwitchCache;
}
@Nullable
}
- void installDefNATRouteInDPN(BigInteger dpnId, long vpnId, TypedWriteTransaction<Configuration> confTx) {
+ public void installDefNATRouteInDPN(BigInteger dpnId, long vpnId, TypedWriteTransaction<Configuration> confTx) {
FlowEntity flowEntity = buildDefNATFlowEntity(dpnId, vpnId);
if (flowEntity == null) {
LOG.error("installDefNATRouteInDPN : Flow entity received is NULL."
mdsalManager.addFlow(confTx, flowEntity);
}
- void installDefNATRouteInDPN(BigInteger dpnId, long bgpVpnId, long routerId,
+ public void installDefNATRouteInDPN(BigInteger dpnId, long bgpVpnId, long routerId,
TypedWriteTransaction<Configuration> confTx) {
FlowEntity flowEntity = buildDefNATFlowEntity(dpnId, bgpVpnId, routerId);
if (flowEntity == null) {
mdsalManager.addFlow(confTx, flowEntity);
}
- void installDefNATRouteInDPN(BigInteger dpnId, long vpnId, String subnetId) {
+ public void installDefNATRouteInDPN(BigInteger dpnId, long vpnId, String subnetId) {
FlowEntity flowEntity = NatUtil.buildDefaultNATFlowEntityForExternalSubnet(dpnId, vpnId, subnetId, idManager);
if (flowEntity == null) {
LOG.error("installDefNATRouteInDPN : Flow entity received is NULL."
mdsalManager.installFlow(flowEntity);
}
- void removeDefNATRouteInDPN(BigInteger dpnId, long vpnId, TypedReadWriteTransaction<Configuration> confTx)
+ public void removeDefNATRouteInDPN(BigInteger dpnId, long vpnId, TypedReadWriteTransaction<Configuration> confTx)
throws ExecutionException, InterruptedException {
FlowEntity flowEntity = buildDefNATFlowEntity(dpnId, vpnId);
if (flowEntity == null) {
mdsalManager.removeFlow(confTx, flowEntity);
}
- void removeDefNATRouteInDPN(BigInteger dpnId, long bgpVpnId, long routerId,
+ public void removeDefNATRouteInDPN(BigInteger dpnId, long bgpVpnId, long routerId,
TypedReadWriteTransaction<Configuration> confTx) throws ExecutionException, InterruptedException {
FlowEntity flowEntity = buildDefNATFlowEntity(dpnId, bgpVpnId, routerId);
if (flowEntity == null) {
mdsalManager.removeFlow(confTx, flowEntity);
}
- void addOrDelDefaultFibRouteToSNATForSubnet(Subnets subnet, String networkId, int flowAction, long vpnId) {
- String subnetId = subnet.getId().getValue();
- InstanceIdentifier<VpnInstanceOpDataEntry> networkVpnInstanceIdentifier =
- NatUtil.getVpnInstanceOpDataIdentifier(networkId);
- Optional<VpnInstanceOpDataEntry> networkVpnInstanceOp =
- SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
- LogicalDatastoreType.OPERATIONAL, networkVpnInstanceIdentifier);
-
- if (!networkVpnInstanceOp.isPresent()) {
- LOG.debug("addOrDelDefaultFibRouteToSNATForSubnet : Cannot create/remove default FIB route to SNAT flow "
- + "for subnet {} vpn-instance-op-data entry for network {} does not exist",
- subnetId, networkId);
- return;
- }
-
- List<VpnToDpnList> dpnListInVpn = networkVpnInstanceOp.get().getVpnToDpnList();
- if (dpnListInVpn == null) {
- LOG.debug("addOrDelDefaultFibRouteToSNATForSubnet : Will not add/remove default NAT flow for subnet {} "
- + "no dpn set for vpn instance {}", subnetId, networkVpnInstanceOp.get());
+ public void addOrDelDefaultFibRouteToSNATForSubnet(Subnets subnet, String networkId, int flowAction, long vpnId) {
+ String providerNet = NatUtil.getElanInstancePhysicalNetwok(networkId, dataBroker);
+ Set<BigInteger> dpnList = natSwitchCache.getSwitchesConnectedToExternal(providerNet);
- return;
+ for (BigInteger dpn : dpnList) {
+ addOrDelDefaultFibRouteToSNATForSubnetInDpn(subnet, networkId, flowAction, vpnId, dpn);
}
+ }
- for (VpnToDpnList dpn : dpnListInVpn) {
- String macAddress = NatUtil.getSubnetGwMac(dataBroker, subnet.getId(), networkId);
- extNetGroupInstaller.installExtNetGroupEntry(new Uuid(networkId), subnet.getId(),
- dpn.getDpnId(), macAddress);
- FlowEntity flowEntity = NatUtil.buildDefaultNATFlowEntityForExternalSubnet(dpn.getDpnId(),
- vpnId, subnetId, idManager);
- if (flowAction == NwConstants.ADD_FLOW || flowAction == NwConstants.MOD_FLOW) {
- LOG.info("addOrDelDefaultFibRouteToSNATForSubnet : Installing flow {} for subnetId {},"
- + "vpnId {} on dpn {}", flowEntity, subnetId, vpnId, dpn.getDpnId());
- jobCoordinator.enqueueJob(NatUtil.getDefaultFibRouteToSNATForSubnetJobKey(subnetId, dpn.getDpnId()),
- () -> Collections.singletonList(mdsalManager.installFlow(flowEntity)));
- } else {
- LOG.info("addOrDelDefaultFibRouteToSNATForSubnet : Removing flow for subnetId {},"
- + "vpnId {} with dpn {}", subnetId, vpnId, dpn);
- jobCoordinator.enqueueJob(NatUtil.getDefaultFibRouteToSNATForSubnetJobKey(subnetId, dpn.getDpnId()),
- () -> Collections.singletonList(mdsalManager.removeFlow(flowEntity)));
- }
+ public void addOrDelDefaultFibRouteToSNATForSubnetInDpn(Subnets subnet, String networkId, int flowAction,
+ long vpnId, BigInteger dpn) {
+ String subnetId = subnet.getId().getValue();
+ String macAddress = NatUtil.getSubnetGwMac(dataBroker, subnet.getId(), networkId);
+ extNetGroupInstaller.installExtNetGroupEntry(new Uuid(networkId), subnet.getId(),
+ dpn, macAddress);
+ FlowEntity flowEntity = NatUtil.buildDefaultNATFlowEntityForExternalSubnet(dpn,
+ vpnId, subnetId, idManager);
+ if (flowAction == NwConstants.ADD_FLOW || flowAction == NwConstants.MOD_FLOW) {
+ LOG.info("addOrDelDefaultFibRouteToSNATForSubnet : Installing flow {} for subnetId {},"
+ + "vpnId {} on dpn {}", flowEntity, subnetId, vpnId, dpn);
+ jobCoordinator.enqueueJob(NatUtil.getDefaultFibRouteToSNATForSubnetJobKey(subnetId, dpn),
+ () -> Collections.singletonList(mdsalManager.installFlow(flowEntity)));
+ } else {
+ LOG.info("addOrDelDefaultFibRouteToSNATForSubnet : Removing flow for subnetId {},"
+ + "vpnId {} with dpn {}", subnetId, vpnId, dpn);
+ jobCoordinator.enqueueJob(NatUtil.getDefaultFibRouteToSNATForSubnetJobKey(subnetId, dpn),
+ () -> Collections.singletonList(mdsalManager.removeFlow(flowEntity)));
}
}
}