use the provider mappings for external group 34/78434/11
authorAswin Suryanarayanan <asuryana@redhat.com>
Tue, 4 Dec 2018 10:08:52 +0000 (15:38 +0530)
committerSam Hague <shague@redhat.com>
Thu, 27 Dec 2018 17:12:19 +0000 (17:12 +0000)
The dpn list for populating the external network is now retrieved from
provider mapping
instead of dpn-vpn list for flat/vlan external network.

NETVIRT-1518
Missing FIB flows when subnet is created immediately after the network
create while using vlan external networks.

Change-Id: Ice1f18eb3e903ec4334815f50f88b2ec030be1d5
Signed-off-by: Aswin Suryanarayanan <asuryana@redhat.com>
12 files changed:
natservice/api/src/main/java/org/opendaylight/netvirt/natservice/api/CentralizedSwitchScheduler.java
natservice/api/src/main/java/org/opendaylight/netvirt/natservice/api/NatSwitchCache.java [new file with mode: 0644]
natservice/api/src/main/java/org/opendaylight/netvirt/natservice/api/NatSwitchCacheListener.java [new file with mode: 0644]
natservice/api/src/main/java/org/opendaylight/netvirt/natservice/api/SwitchInfo.java [new file with mode: 0644]
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/ha/NatSwitchCacheImpl.java [new file with mode: 0644]
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/ha/SnatNodeEventListener.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/ha/WeightedCentralizedSwitchScheduler.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/ExternalSubnetVpnInstanceListener.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/FloatingIPListener.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/NatSwitchCacheListenerImpl.java [new file with mode: 0644]
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/NatUtil.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/SNATDefaultRouteProgrammer.java

index c5875af28f90d3f74e7c93d454467be0ec127c5c..80b7390f3c30ac9a258485b4331f86ce55f0117c 100644 (file)
@@ -42,27 +42,4 @@ public interface CentralizedSwitchScheduler {
      * @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);
-
 }
diff --git a/natservice/api/src/main/java/org/opendaylight/netvirt/natservice/api/NatSwitchCache.java b/natservice/api/src/main/java/org/opendaylight/netvirt/natservice/api/NatSwitchCache.java
new file mode 100644 (file)
index 0000000..93aed90
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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);
+
+
+}
diff --git a/natservice/api/src/main/java/org/opendaylight/netvirt/natservice/api/NatSwitchCacheListener.java b/natservice/api/src/main/java/org/opendaylight/netvirt/natservice/api/NatSwitchCacheListener.java
new file mode 100644 (file)
index 0000000..0f1b0ec
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * 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);
+
+}
diff --git a/natservice/api/src/main/java/org/opendaylight/netvirt/natservice/api/SwitchInfo.java b/natservice/api/src/main/java/org/opendaylight/netvirt/natservice/api/SwitchInfo.java
new file mode 100644 (file)
index 0000000..a89fee3
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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;
+    }
+
+
+}
diff --git a/natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/ha/NatSwitchCacheImpl.java b/natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/ha/NatSwitchCacheImpl.java
new file mode 100644 (file)
index 0000000..25b6fa9
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * 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;
+    }
+}
index 081280c0ae0e11498b3518188c8a92058f52b380..b93b6a9a5ab20af3918482920c6e31bc3051ccfb 100644 (file)
@@ -17,7 +17,7 @@ import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 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;
@@ -33,16 +33,16 @@ import org.slf4j.LoggerFactory;
 @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
@@ -50,7 +50,7 @@ public class SnatNodeEventListener  extends AbstractClusteredAsyncDataTreeChange
         NodeKey nodeKey = dataObjectModification.key();
         BigInteger dpnId = MDSALUtil.getDpnIdFromNodeName(nodeKey.getId());
         LOG.info("Dpn removed {}", dpnId);
-        centralizedSwitchScheduler.removeSwitch(dpnId);
+        centralizedSwitchCache.removeSwitch(dpnId);
     }
 
     @Override
@@ -64,6 +64,6 @@ public class SnatNodeEventListener  extends AbstractClusteredAsyncDataTreeChange
         NodeKey nodeKey = dataObjectModification.key();
         BigInteger dpnId = MDSALUtil.getDpnIdFromNodeName(nodeKey.getId());
         LOG.info("Dpn added {}", dpnId);
-        centralizedSwitchScheduler.addSwitch(dpnId);
+        centralizedSwitchCache.addSwitch(dpnId);
     }
 }
index 3c0c2888b79dc7649601aa1a7285bbe5c35f63cc..86bf977355494dc7c75f6e6c8715e238b4fab7d5 100644 (file)
@@ -36,6 +36,9 @@ import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
 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;
@@ -57,7 +60,7 @@ import org.slf4j.Logger;
 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);
 
@@ -71,8 +74,10 @@ public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchSche
     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;
@@ -82,6 +87,7 @@ public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchSche
         } else {
             this.natMode = NatserviceConfig.NatMode.Controller;
         }
+        natSwitchCache.register(this);
     }
 
     @Override
@@ -206,8 +212,6 @@ public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchSche
         }
     }
 
-
-
     private void deleteFromDpnMaps(String routerName, List<Uuid> deletedSubnetIds, BigInteger primarySwitchId) {
         if (deletedSubnetIds == null || deletedSubnetIds.isEmpty()) {
             LOG.debug("deleteFromDpnMaps no subnets associated with {}", routerName);
@@ -241,19 +245,17 @@ public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchSche
     }
 
     @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;
@@ -262,7 +264,7 @@ public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchSche
                         LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(ExtRouters.class));
             } catch (ReadFailedException e) {
                 LOG.error("addSwitch: Error reading external routers", e);
-                return false;
+                return;
             }
 
             if (optRouters.isPresent()) {
@@ -278,7 +280,7 @@ public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchSche
                 }
             }
         }
-        return true;
+        return;
     }
 
     private boolean isPrimarySwitchAllocatedForRouter(String routerName) {
@@ -299,7 +301,8 @@ public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchSche
     }
 
     @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();
@@ -317,7 +320,7 @@ public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchSche
             }
             switchWeightMap.remove(dpnId);
         }
-        return true;
+        return;
     }
 
     private NaptSwitches getNaptSwitches() {
@@ -374,17 +377,8 @@ public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchSche
         }
     }
 
-    @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;
         }
index 2dc7bd707419eb6529d7d41bbad499bc1fc8bfa5..d72905b2e493cdeb01cf1d95560f69514bc6c50b 100644 (file)
@@ -8,25 +8,18 @@
 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;
@@ -42,20 +35,15 @@ public class ExternalSubnetVpnInstanceListener extends AsyncDataTreeChangeListen
     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
@@ -128,51 +116,8 @@ public class ExternalSubnetVpnInstanceListener extends AsyncDataTreeChangeListen
         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
index 75ad2ad00a4f49b8333c6565ceeef5212afd3797..a5b1313a742bedef0a25a80281c49af19c354827 100644 (file)
@@ -53,6 +53,7 @@ import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
 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;
@@ -83,6 +84,7 @@ public class FloatingIPListener extends AsyncDataTreeChangeListenerBase<Internal
     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,
@@ -90,7 +92,8 @@ public class FloatingIPListener extends AsyncDataTreeChangeListenerBase<Internal
                               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);
@@ -100,6 +103,7 @@ public class FloatingIPListener extends AsyncDataTreeChangeListenerBase<Internal
         this.defaultRouteProgrammer = snatDefaultRouteProgrammer;
         this.coordinator = coordinator;
         this.centralizedSwitchScheduler = centralizedSwitchScheduler;
+        this.natSwitchCache = natSwitchCache;
     }
 
     @Override
@@ -460,7 +464,7 @@ public class FloatingIPListener extends AsyncDataTreeChangeListenerBase<Internal
         // 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);
             }
diff --git a/natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/NatSwitchCacheListenerImpl.java b/natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/NatSwitchCacheListenerImpl.java
new file mode 100644 (file)
index 0000000..d83d202
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * 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 */
+    }
+}
index 8fd8f4d83e2ba59a953ab9093b5c73e2ed3b7fb2..af10252d8e25674cf1b34a63f1e121687822aa31 100644 (file)
@@ -2571,4 +2571,21 @@ public final class NatUtil {
     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;
+
+    }
 }
index baf9308b4645303bd33810c2d2fbc116fea96ea1..7efb852268d531ce212e1bbc0d347814b7af89a2 100644 (file)
@@ -7,22 +7,19 @@
  */
 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;
@@ -37,12 +34,10 @@ import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
 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;
 
@@ -56,17 +51,20 @@ public class SNATDefaultRouteProgrammer {
     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
@@ -137,7 +135,7 @@ public class SNATDefaultRouteProgrammer {
 
     }
 
-    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."
@@ -148,7 +146,7 @@ public class SNATDefaultRouteProgrammer {
         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) {
@@ -160,7 +158,7 @@ public class SNATDefaultRouteProgrammer {
         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."
@@ -171,7 +169,7 @@ public class SNATDefaultRouteProgrammer {
         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) {
@@ -183,7 +181,7 @@ public class SNATDefaultRouteProgrammer {
         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) {
@@ -195,46 +193,33 @@ public class SNATDefaultRouteProgrammer {
         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)));
         }
     }
 }