vpnmanager: misc fixes related to dual stack per neutron port. 51/63951/30
authorPhilippe Guibert <philippe.guibert@6wind.com>
Mon, 2 Oct 2017 17:33:10 +0000 (18:33 +0100)
committerVivekanandan Narasimhan <n.vivekanandan@ericsson.com>
Mon, 13 Nov 2017 05:23:26 +0000 (05:23 +0000)
- route interface state applies to more than one IP.
introduction of dual stack makes it possible to handle more than one
fixed IP, then more than one associated subnet. This change applied the
change of yang port-op-data-entry structure to support a list of
subnet-ids. This information is updated in
SubnetRouteInterfaceStateChangeListener, where the list of subnets is
extracted from the Neutron port.
- vpnmanager: remove and update prefixtointerface for dual stack addresses
Due to the possibility to have two primary IP addresses per port, some
VPN migration scenarios may not work with the other IP address. The code
is adapted to parse all the primary adjacencies of the VPN Interface.

Change-Id: I2936014f9aaa5b42b820466affd3ada31695860d
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
vpnservice/vpnmanager/vpnmanager-api/src/main/yang/odl-l3vpn.yang
vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/SubnetOpDpnManager.java
vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/SubnetRouteInterfaceStateChangeListener.java
vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/TunnelInterfaceStateListener.java
vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnInterfaceOpListener.java
vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnSubnetRouteHandler.java
vpnservice/vpnmanager/vpnmanager-impl/src/test/java/org/opendaylight/netvirt/vpnmanager/test/SubnetOpDpnManagerTest.java
vpnservice/vpnmanager/vpnmanager-impl/src/test/java/org/opendaylight/netvirt/vpnmanager/test/VpnSubnetRouteHandlerTest.java

index 910c0d29216af74e85b4c074fa9ef96e6aab50e0..50887530ed9c0daa56d51d430e6c240d515b9c0e 100644 (file)
@@ -473,7 +473,7 @@ module odl-l3vpn {
                 type  string;
                 description "UUID in string format representing the port ";
             }
-            leaf subnet-id {
+            leaf-list subnet-ids {
                 type  yang:uuid;
                 description "Back reference to obtain the subnet for a port ";
             }
index e734221e0ab6aa90f14a5cfb5268fa798b211320..ac7a3c7da6b937ec6ce8576e8ee0752a5f4faa6b 100644 (file)
@@ -145,10 +145,19 @@ public class SubnetOpDpnManager {
                 // Create PortOpDataEntry only if not present
                 portOpBuilder =
                     new PortOpDataEntryBuilder().setKey(new PortOpDataEntryKey(intfName)).setPortId(intfName);
-                portOpBuilder.setSubnetId(subnetId);
+                List<Uuid> listSubnet = new ArrayList<>();
+                listSubnet.add(subnetId);
+                portOpBuilder.setSubnetIds(listSubnet);
             } else {
+                List<Uuid> listSubnet = optionalPortOp.get().getSubnetIds();
                 portOpBuilder = new PortOpDataEntryBuilder(optionalPortOp.get());
-                portOpBuilder.setSubnetId(subnetId);
+                if (listSubnet == null) {
+                    listSubnet = new ArrayList<Uuid>();
+                }
+                if (!listSubnet.contains(subnetId)) {
+                    listSubnet.add(subnetId);
+                }
+                portOpBuilder.setSubnetIds(listSubnet);
             }
             if (dpnId != null && !dpnId.equals(BigInteger.ZERO)) {
                 portOpBuilder.setDpnId(dpnId);
@@ -156,8 +165,8 @@ public class SubnetOpDpnManager {
             portOpEntry = portOpBuilder.build();
             SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, portOpIdentifier,
                 portOpEntry);
-            LOG.info("addPortOpDataEntry: Created PortOpData entry for port {} with DPNId {} intfName {}",
-                    intfName, dpnId, intfName);
+            LOG.info("addPortOpDataEntry: Created PortOpData entry for port {} with DPNId {} subnetId {}",
+                     intfName, dpnId, subnetId.getValue());
         } catch (TransactionCommitFailedException ex) {
             LOG.error("addPortOpDataEntry: Addition of Interface {} for SubnetToDpn on subnet {} with DPN {} failed",
                     intfName, subnetId.getValue(), dpnId, ex);
@@ -203,7 +212,7 @@ public class SubnetOpDpnManager {
         return dpnRemoved;
     }
 
-    public PortOpDataEntry removePortOpDataEntry(String intfName) {
+    public PortOpDataEntry removePortOpDataEntry(String intfName, Uuid subnetId) {
         // Remove PortOpData and return out
         InstanceIdentifier<PortOpDataEntry> portOpIdentifier =
             InstanceIdentifier.builder(PortOpData.class).child(PortOpDataEntry.class,
@@ -217,8 +226,31 @@ public class SubnetOpDpnManager {
             return null;
         } else {
             portOpEntry = optionalPortOp.get();
-            MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, portOpIdentifier);
-            LOG.info("removePortOpDataEntry: Deleted portOpData entry for port {}", intfName);
+            List<Uuid> listSubnet = portOpEntry.getSubnetIds();
+            if (listSubnet == null) {
+                listSubnet = new ArrayList<Uuid>();
+            }
+            if (subnetId != null && listSubnet.contains(subnetId)) {
+                listSubnet.remove(subnetId);
+            }
+            if (listSubnet.isEmpty() || subnetId == null) {
+                MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, portOpIdentifier);
+                LOG.info("removePortOpDataEntry: Deleted portOpData entry for port {}", intfName);
+            } else {
+                try {
+                    PortOpDataEntryBuilder portOpBuilder = null;
+                    portOpBuilder = new PortOpDataEntryBuilder(portOpEntry);
+                    portOpBuilder.setSubnetIds(listSubnet);
+                    SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, portOpIdentifier,
+                        portOpEntry);
+                    LOG.info("removePortOpDataEntry: Updated PortOpData entry for port {} with removing subnetId {}",
+                        intfName, subnetId.getValue());
+                } catch (TransactionCommitFailedException ex) {
+                    LOG.error("removePortOpDataEntry failed: Updated PortOpData entry for port {}"
+                        + " with removing subnetId {}", intfName, subnetId.getValue());
+                }
+                return null;
+            }
         }
         return portOpEntry;
     }
index c54121c8f32a45af65fb149a96d532e2ff48980a..fea4b8bd3469ff9e114ee5636fc0c60eb3443225 100644 (file)
@@ -25,6 +25,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
 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.l3vpn.rev130911.port.op.data.PortOpDataEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
@@ -73,34 +74,36 @@ public class SubnetRouteInterfaceStateChangeListener extends AsyncDataTreeChange
     @Override
     protected void add(InstanceIdentifier<Interface> identifier, Interface intrf) {
         LOG.trace("{} add: Received interface {} up event", LOGGING_PREFIX, intrf);
-        final Uuid subnetId;
+        final List<Uuid> subnetIdList;
         try {
             if (L2vlan.class.equals(intrf.getType())) {
                 LOG.trace("SubnetRouteInterfaceListener add: Received interface {} up event", intrf);
                 if (intrf.getOperStatus().equals(Interface.OperStatus.Up)) {
-                    subnetId = getSubnetId(intrf);
-                    if (subnetId == null) {
+                    subnetIdList = getSubnetId(intrf);
+                    if (subnetIdList == null || subnetIdList.isEmpty()) {
                         LOG.trace("SubnetRouteInterfaceListener add: Port {} doesnt exist in configDS",
                                 intrf.getName());
                         return;
                     }
-                    DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
-                    dataStoreCoordinator.enqueueJob("SUBNETROUTE-" + subnetId,
-                        () -> {
-                            List<ListenableFuture<Void>> futures = new ArrayList<>();
-                            String interfaceName = intrf.getName();
-                            LOG.info("{} add: Received port UP event for interface {} subnetId {}",
-                                    LOGGING_PREFIX, interfaceName, subnetId.getValue());
-                            try {
-                                BigInteger dpnId = InterfaceUtils.getDpIdFromInterface(intrf);
-                                vpnSubnetRouteHandler.onInterfaceUp(dpnId, intrf.getName(), subnetId);
-                            } catch (Exception e) {
-                                LOG.error("{} add: Unable to obtain dpnId for interface {} in subnet {},"
-                                        + " subnetroute inclusion for this interface failed with exception {}",
-                                        LOGGING_PREFIX, interfaceName, subnetId.getValue(), e);
-                            }
-                            return futures;
-                        });
+                    for (Uuid subnetId : subnetIdList) {
+                        DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
+                        dataStoreCoordinator.enqueueJob("SUBNETROUTE-" + subnetId,
+                            () -> {
+                                String interfaceName = intrf.getName();
+                                LOG.info("{} add: Received port UP event for interface {} subnetId {}",
+                                        LOGGING_PREFIX, interfaceName, subnetId);
+                                try {
+                                    BigInteger dpnId = InterfaceUtils.getDpIdFromInterface(intrf);
+                                    vpnSubnetRouteHandler.onInterfaceUp(dpnId, intrf.getName(), subnetId);
+                                } catch (Exception e) {
+                                    LOG.error("{} add: Unable to obtain dpnId for interface {} in subnet {},"
+                                            + " subnetroute inclusion for this interface failed with exception {}",
+                                            LOGGING_PREFIX, interfaceName, subnetId, e);
+                                }
+                                List<ListenableFuture<Void>> futures = new ArrayList<>();
+                                return futures;
+                            });
+                    }
                 }
             }
             LOG.info("{} add: Processed interface {} up event", LOGGING_PREFIX, intrf.getName());
@@ -114,43 +117,45 @@ public class SubnetRouteInterfaceStateChangeListener extends AsyncDataTreeChange
     @SuppressWarnings("checkstyle:IllegalCatch")
     @Override
     protected void remove(InstanceIdentifier<Interface> identifier, Interface intrf) {
-        final Uuid subnetId;
+        final List<Uuid> subnetIdList;
         try {
             if (L2vlan.class.equals(intrf.getType())) {
                 LOG.trace("SubnetRouteInterfaceListener remove: Received interface {} down event", intrf);
-                subnetId = getSubnetId(intrf);
-                if (subnetId == null) {
-                    LOG.trace("SubnetRouteInterfaceListener add: Port {} doesnt exist in configDS",
+                subnetIdList = getSubnetId(intrf);
+                if (subnetIdList == null || subnetIdList.isEmpty()) {
+                    LOG.trace("SubnetRouteInterfaceListener remove: Port {} doesnt exist in configDS",
                             intrf.getName());
                     return;
                 }
-                DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
-                dataStoreCoordinator.enqueueJob("SUBNETROUTE-" + subnetId,
-                    () -> {
-                        String interfaceName = intrf.getName();
-                        BigInteger dpnId = BigInteger.ZERO;
-                        LOG.info("{} remove: Received port DOWN event for interface {} in subnet {} ",
-                                LOGGING_PREFIX, interfaceName, subnetId.getValue());
-                        try {
-                            dpnId = InterfaceUtils.getDpIdFromInterface(intrf);
-                        } catch (Exception e) {
-                            LOG.error("{} remove: Unable to retrieve dpnId for interface {} in subnet {}. "
-                                            + "Fetching from vpn interface itself due to exception {}",
-                                    LOGGING_PREFIX, intrf.getName(), subnetId.getValue(), e);
-                            InstanceIdentifier<VpnInterface> id = VpnUtil
-                                    .getVpnInterfaceIdentifier(interfaceName);
-                            Optional<VpnInterface> optVpnInterface = VpnUtil.read(dataBroker,
-                                    LogicalDatastoreType.OPERATIONAL, id);
-                            if (optVpnInterface.isPresent()) {
-                                dpnId = optVpnInterface.get().getDpnId();
+                for (Uuid subnetId : subnetIdList) {
+                    DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
+                    dataStoreCoordinator.enqueueJob("SUBNETROUTE-" + subnetId,
+                        () -> {
+                            String interfaceName = intrf.getName();
+                            BigInteger dpnId = BigInteger.ZERO;
+                            LOG.info("{} remove: Received port DOWN event for interface {} in subnet {} ",
+                                    LOGGING_PREFIX, interfaceName, subnetId);
+                            try {
+                                dpnId = InterfaceUtils.getDpIdFromInterface(intrf);
+                            } catch (Exception e) {
+                                LOG.error("{} remove: Unable to retrieve dpnId for interface {} in subnet {}. "
+                                                + "Fetching from vpn interface itself due to exception {}",
+                                        LOGGING_PREFIX, intrf.getName(), subnetId, e);
+                                InstanceIdentifier<VpnInterface> id = VpnUtil
+                                        .getVpnInterfaceIdentifier(interfaceName);
+                                Optional<VpnInterface> optVpnInterface = VpnUtil.read(dataBroker,
+                                        LogicalDatastoreType.OPERATIONAL, id);
+                                if (optVpnInterface.isPresent()) {
+                                    dpnId = optVpnInterface.get().getDpnId();
+                                }
+                            }
+                            if (!dpnId.equals(BigInteger.ZERO)) {
+                                vpnSubnetRouteHandler.onInterfaceDown(dpnId, intrf.getName(), subnetId);
                             }
-                        }
-                        if (!dpnId.equals(BigInteger.ZERO)) {
-                            vpnSubnetRouteHandler.onInterfaceDown(dpnId, intrf.getName(), subnetId);
-                        }
-                        List<ListenableFuture<Void>> futures = new ArrayList<>();
-                        return futures;
-                    });
+                            List<ListenableFuture<Void>> futures = new ArrayList<>();
+                            return futures;
+                        });
+                }
             }
             LOG.info("{} remove: Processed interface {} down event in ", LOGGING_PREFIX, intrf.getName());
         } catch (Exception e) {
@@ -164,56 +169,58 @@ public class SubnetRouteInterfaceStateChangeListener extends AsyncDataTreeChange
     @Override
     protected void update(InstanceIdentifier<Interface> identifier,
         Interface original, Interface update) {
-        final Uuid subnetId;
+        final List<Uuid> subnetIdList;
         try {
             String interfaceName = update.getName();
             if (L2vlan.class.equals(update.getType())) {
                 LOG.trace("{} update: Operation Interface update event - Old: {}, New: {}", LOGGING_PREFIX,
                     original, update);
-                subnetId = getSubnetId(update);
-                if (subnetId == null) {
-                    LOG.trace("SubnetRouteInterfaceListener update: Port {} doesnt exist in configDS",
+                subnetIdList = getSubnetId(update);
+                if ((subnetIdList == null) || (subnetIdList.isEmpty())) {
+                    LOG.error("SubnetRouteInterfaceListener update: Port {} doesnt exist in configDS",
                             update.getName());
                     return;
                 }
-                DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
-                dataStoreCoordinator.enqueueJob("SUBNETROUTE-" + subnetId,
-                    () -> {
-                        List<ListenableFuture<Void>> futures = new ArrayList<>();
-                        BigInteger dpnId = BigInteger.ZERO;
-                        try {
-                            dpnId = InterfaceUtils.getDpIdFromInterface(update);
-                        } catch (Exception e) {
-                            LOG.error("{} remove: Unable to retrieve dpnId for interface {} in subnet  {}. "
-                                    + "Fetching from vpn interface itself due to exception {}", LOGGING_PREFIX,
-                                    update.getName(), subnetId.getValue(), e);
-                            InstanceIdentifier<VpnInterface> id = VpnUtil
-                                    .getVpnInterfaceIdentifier(interfaceName);
-                            Optional<VpnInterface> optVpnInterface = VpnUtil.read(dataBroker,
-                                    LogicalDatastoreType.OPERATIONAL, id);
-                            if (optVpnInterface.isPresent()) {
-                                dpnId = optVpnInterface.get().getDpnId();
+                for (Uuid subnetId : subnetIdList) {
+                    DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
+                    dataStoreCoordinator.enqueueJob("SUBNETROUTE-" + subnetId,
+                        () -> {
+                            List<ListenableFuture<Void>> futures = new ArrayList<>();
+                            BigInteger dpnId = BigInteger.ZERO;
+                            try {
+                                dpnId = InterfaceUtils.getDpIdFromInterface(update);
+                            } catch (Exception e) {
+                                LOG.error("{} remove: Unable to retrieve dpnId for interface {} in subnet  {}. "
+                                        + "Fetching from vpn interface itself due to exception {}", LOGGING_PREFIX,
+                                        update.getName(), subnetId, e);
+                                InstanceIdentifier<VpnInterface> id = VpnUtil
+                                        .getVpnInterfaceIdentifier(interfaceName);
+                                Optional<VpnInterface> optVpnInterface = VpnUtil.read(dataBroker,
+                                        LogicalDatastoreType.OPERATIONAL, id);
+                                if (optVpnInterface.isPresent()) {
+                                    dpnId = optVpnInterface.get().getDpnId();
+                                }
                             }
-                        }
-                        if (!dpnId.equals(BigInteger.ZERO)) {
-                            if (update.getOperStatus().equals(Interface.OperStatus.Up)) {
-                                LOG.info("{} update: Received port UP event for interface {} in subnet {}",
-                                        LOGGING_PREFIX, update.getName(), subnetId.getValue());
-                                vpnSubnetRouteHandler.onInterfaceUp(dpnId, update.getName(), subnetId);
-                            } else if (update.getOperStatus().equals(Interface.OperStatus.Down)
-                                    || update.getOperStatus().equals(Interface.OperStatus.Unknown)) {
-                                /*
-                                 * If the interface went down voluntarily (or) if the interface is not
-                                 * reachable from control-path involuntarily, trigger subnetRoute election
-                                 */
-                                LOG.info("{} update: Received port {} event for interface {} in subnet {} ",
-                                        LOGGING_PREFIX, update.getOperStatus().equals(Interface.OperStatus.Unknown)
-                                                ? "UNKNOWN" : "DOWN", update.getName(), subnetId.getValue());
-                                vpnSubnetRouteHandler.onInterfaceDown(dpnId, update.getName(), subnetId);
+                            if (!dpnId.equals(BigInteger.ZERO)) {
+                                if (update.getOperStatus().equals(Interface.OperStatus.Up)) {
+                                    LOG.info("{} update: Received port UP event for interface {} in subnet {}",
+                                        LOGGING_PREFIX, update.getName(), subnetId);
+                                    vpnSubnetRouteHandler.onInterfaceUp(dpnId, update.getName(), subnetId);
+                                } else if (update.getOperStatus().equals(Interface.OperStatus.Down)
+                                     || update.getOperStatus().equals(Interface.OperStatus.Unknown)) {
+                                    /*
+                                     * If the interface went down voluntarily (or) if the interface is not
+                                     * reachable from control-path involuntarily, trigger subnetRoute election
+                                     */
+                                    LOG.info("{} update: Received port {} event for interface {} in subnet {} ",
+                                            LOGGING_PREFIX, update.getOperStatus().equals(Interface.OperStatus.Unknown)
+                                            ? "UNKNOWN" : "DOWN", update.getName(), subnetId);
+                                    vpnSubnetRouteHandler.onInterfaceDown(dpnId, update.getName(), subnetId);
+                                }
                             }
-                        }
-                        return futures;
-                    });
+                            return futures;
+                        });
+                }
             }
             LOG.info("{} update: Processed Interface {} update event", LOGGING_PREFIX, update.getName());
         } catch (Exception e) {
@@ -222,24 +229,33 @@ public class SubnetRouteInterfaceStateChangeListener extends AsyncDataTreeChange
         }
     }
 
-    protected Uuid getSubnetId(Interface intrf) {
-
+    protected List<Uuid> getSubnetId(Interface intrf) {
+        List<Uuid> listSubnetIds = new ArrayList<Uuid>();
         if (!NeutronUtils.isUuid(intrf.getName())) {
             LOG.debug("SubnetRouteInterfaceListener: Interface {} doesnt have valid uuid pattern", intrf.getName());
-            return null;
+            return listSubnetIds;
         }
 
         PortOpDataEntry portOpEntry = subOpDpnManager.getPortOpDataEntry(intrf.getName());
         if (portOpEntry != null) {
-            return portOpEntry.getSubnetId();
+            List<Uuid> subnet = portOpEntry.getSubnetIds();
+            if (subnet != null) {
+                return subnet;
+            }
+            return listSubnetIds;
         }
         LOG.trace("SubnetRouteInterfaceListener : Received Port {} event for {} that is not part of subnetRoute",
                 intrf.getOperStatus(), intrf.getName());
         Port port = neutronVpnManager.getNeutronPort(intrf.getName());
-        if (port != null && port.getFixedIps() != null && port.getFixedIps().size() > 0) {
-            return port.getFixedIps().get(0).getSubnetId();
-        } else {
-            return null;
+        if (port == null) {
+            return listSubnetIds;
+        }
+        List<FixedIps> portIps = port.getFixedIps();
+        if (port.getFixedIps() != null) {
+            for (FixedIps portIp : portIps) {
+                listSubnetIds.add(portIp.getSubnetId());
+            }
         }
+        return listSubnetIds;
     }
 }
index 253cc965f2d6746919bcdfab60b940b2cd87b184..66944becb87668b5aa5cfd6bada40188963bc125 100644 (file)
@@ -333,9 +333,13 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas
                     Optional<PortOpDataEntry> optionalPortOp =
                         VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, portOpIdentifier);
                     if (optionalPortOp.isPresent()) {
-                        Uuid subnetId = optionalPortOp.get().getSubnetId();
-                        if (!subnetList.contains(subnetId)) {
-                            subnetList.add(subnetId);
+                        List<Uuid> subnetIdList = optionalPortOp.get().getSubnetIds();
+                        if (subnetIdList != null) {
+                            for (Uuid subnetId : subnetIdList) {
+                                if (!subnetList.contains(subnetId)) {
+                                    subnetList.add(subnetId);
+                                }
+                            }
                         }
                     }
                     //Populate the map for VpnId-to-Rd
index d6f617da2bbe5806b2ad3d0bb5d8fa7f2da62a64..4d03d36b94811b6f07b044d303f460d29163bff1 100644 (file)
@@ -23,6 +23,7 @@ import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev14081
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adjacencies;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency.AdjacencyType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
 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.to.vpn.id.VpnInstance;
@@ -122,23 +123,31 @@ public class VpnInterfaceOpListener extends AsyncDataTreeChangeListenerBase<VpnI
                  */
                 // TODO(vivek) # It is not yet clear, where we are cleaning up the prefix-to-interface
                 // TODO(vivek) # for primary adjacencies and that has to be fixed.
-                Adjacency adjacency = adjs.getAdjacency().get(0);
                 List<Prefixes> prefixToInterface = new ArrayList<>();
-                Optional<Prefixes> prefix = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
-                    VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
-                        VpnUtil.getIpPrefix(adjacency.getIpAddress())));
-                if (prefix.isPresent()) {
-                    prefixToInterface.add(prefix.get());
-                }
-                if (prefixToInterface.isEmpty()) {
-                    for (String nh : adjacency.getNextHopIpList()) {
-                        prefix = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
-                            VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
-                                VpnUtil.getIpPrefix(nh)));
-                        if (prefix.isPresent()) {
-                            prefixToInterface.add(prefix.get());
+                for (Adjacency adjacency : adjs.getAdjacency()) {
+                    List<Prefixes> prefixToInterfaceLocal = new ArrayList<>();
+                    if (adjacency.getAdjacencyType() != AdjacencyType.PrimaryAdjacency) {
+                        continue;
+                    }
+                    Optional<Prefixes> prefix = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
+                        VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
+                            VpnUtil.getIpPrefix(adjacency.getIpAddress())));
+                    if (prefix.isPresent()) {
+                        prefixToInterfaceLocal.add(prefix.get());
+                    }
+                    if (prefixToInterfaceLocal.isEmpty()) {
+                        for (String nh : adjacency.getNextHopIpList()) {
+                            prefix = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
+                                VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
+                                    VpnUtil.getIpPrefix(nh)));
+                            if (prefix.isPresent()) {
+                                prefixToInterfaceLocal.add(prefix.get());
+                            }
                         }
                     }
+                    if (!prefixToInterfaceLocal.isEmpty()) {
+                        prefixToInterface.addAll(prefixToInterfaceLocal);
+                    }
                 }
                 /*
                  * In VPN Migration scenarios, there is a race condition where we use the new DPNID
@@ -246,26 +255,32 @@ public class VpnInterfaceOpListener extends AsyncDataTreeChangeListenerBase<VpnI
             List<Adjacency> adjList = (adjs != null) ? adjs.getAdjacency() : null;
 
             if (vpnInstOp != null && adjList != null && adjList.size() > 0) {
-                Adjacency adjacency = adjs.getAdjacency().get(0);
                 List<Prefixes> prefixToInterfaceList = new ArrayList<>();
-                Optional<Prefixes> prefixToInterface = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
-                    VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
+                for (Adjacency adjacency : adjs.getAdjacency()) {
+                    List<Prefixes> prefixToInterfaceListLocal = new ArrayList<>();
+                    if (adjacency.getAdjacencyType() != AdjacencyType.PrimaryAdjacency) {
+                        continue;
+                    }
+                    Optional<Prefixes> prefixToInterface = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
+                        VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
                         VpnUtil.getIpPrefix(adjacency.getIpAddress())));
-                if (prefixToInterface.isPresent()) {
-                    prefixToInterfaceList.add(prefixToInterface.get());
-                } else {
-                    for (String adj : adjacency.getNextHopIpList()) {
-                        prefixToInterface = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
-                            VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
-                                VpnUtil.getIpPrefix(adj)));
-                        if (prefixToInterface.isPresent()) {
-                            prefixToInterfaceList.add(prefixToInterface.get());
+                    if (prefixToInterface.isPresent()) {
+                        prefixToInterfaceListLocal.add(prefixToInterface.get());
+                    } else {
+                        for (String adj : adjacency.getNextHopIpList()) {
+                            prefixToInterface = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
+                                VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
+                                    VpnUtil.getIpPrefix(adj)));
+                            if (prefixToInterface.isPresent()) {
+                                prefixToInterfaceListLocal.add(prefixToInterface.get());
+                            }
                         }
                     }
-                }
-                for (Prefixes prefix : prefixToInterfaceList) {
-                    vpnFootprintService.updateVpnToDpnMapping(prefix.getDpnId(), original.getVpnInstanceName(), rd,
-                        interfaceName, null /*ipAddressSourceValuePair*/, false /* delete */);
+                    for (Prefixes prefix : prefixToInterfaceListLocal) {
+                        vpnFootprintService.updateVpnToDpnMapping(prefix.getDpnId(),
+                            original.getVpnInstanceName(), rd,
+                            interfaceName, null /*ipAddressSourceValuePair*/, false /* delete */);
+                    }
                 }
             }
             LOG.info("postProcessVpnInterfaceUpdate: Updated vpn operational data and vpn footprint"
index 2915558cddc1554f0b1216564e3d156801f10ce2..fb3aa12603d0bd9917bbf81aba1182f68d905bb6 100644 (file)
@@ -474,7 +474,8 @@ public class VpnSubnetRouteHandler {
         try {
             VpnUtil.lockSubnet(lockManager, subnetId.getValue());
             try {
-                PortOpDataEntry portOpEntry = subOpDpnManager.removePortOpDataEntry(portId.getValue());
+                PortOpDataEntry portOpEntry = subOpDpnManager.removePortOpDataEntry(portId.getValue(),
+                                                                               subnetmap.getId());
                 if (portOpEntry == null) {
                     return;
                 }
index af28181ad04f70945d5583e920cbf876ea03e941..d27037f1bb57000485fe2d51eb2839d064c4520f 100644 (file)
@@ -90,10 +90,12 @@ public class SubnetOpDpnManagerTest {
     private void setupMocks() {
 
         List<VpnInterfaces> vpnInterfaces = new ArrayList<>();
+        List<Uuid> subnetIdList = new ArrayList<>();
+        subnetIdList.add(subnetId);
         subnetToDpn = new SubnetToDpnBuilder().setDpnId(dpId).setKey(new SubnetToDpnKey(dpId)).setVpnInterfaces(
             vpnInterfaces).build();
-        portOp = new PortOpDataEntryBuilder().setDpnId(dpId).setKey(new PortOpDataEntryKey(infName)).setSubnetId(
-            subnetId).setPortId(portId).build();
+        portOp = new PortOpDataEntryBuilder().setDpnId(dpId).setKey(new PortOpDataEntryKey(infName)).setSubnetIds(
+            subnetIdList).setPortId(portId).build();
         doReturn(mockReadTx).when(dataBroker).newReadOnlyTransaction();
         doReturn(mockWriteTx).when(dataBroker).newWriteOnlyTransaction();
         doReturn(Futures.immediateCheckedFuture(null)).when(mockWriteTx).submit();
@@ -141,7 +143,7 @@ public class SubnetOpDpnManagerTest {
     @Test
     public void testRemovePortOpDataEntryPortOpPresent() {
 
-        subOpDpnManager.removePortOpDataEntry(infName);
+        subOpDpnManager.removePortOpDataEntry(infName, null);
 
         verify(mockWriteTx).delete(LogicalDatastoreType.OPERATIONAL, portOpIdentifier);
     }
@@ -152,7 +154,7 @@ public class SubnetOpDpnManagerTest {
         doReturn(Futures.immediateCheckedFuture(Optional.absent())).when(mockReadTx).read(LogicalDatastoreType
             .OPERATIONAL, portOpIdentifier);
 
-        subOpDpnManager.removePortOpDataEntry(infName);
+        subOpDpnManager.removePortOpDataEntry(infName, null);
 
         verify(mockReadTx).read(LogicalDatastoreType.OPERATIONAL, portOpIdentifier);
 
index 96797db9ee5432d592b020789cb16f43908bfc8a..4b2fc219cd498deb4c08ace06376c7e5f1767a87 100644 (file)
@@ -258,10 +258,12 @@ public class VpnSubnetRouteHandlerTest {
         final List<Uuid> portList = new ArrayList<>();
         final List<PortOpDataEntry> listPortOpDataEntry = new ArrayList<>();
         final List<TunnelEndPoints> tunnelEndPoints = new ArrayList<>();
+        List<Uuid> subnetIdList = new ArrayList<>();
+        subnetIdList.add(subnetId);
         vpnInterfaces.add(vpnIntfaces);
         lowerLayerIfList.add(nodeConnectorId.getValue());
         portOp = new PortOpDataEntryBuilder().setDpnId(dpId).setKey(new PortOpDataEntryKey(tenantId.getValue()))
-            .setSubnetId(subnetId).setPortId(tenantId.getValue()).build();
+            .setSubnetIds(subnetIdList).setPortId(tenantId.getValue()).build();
         subnetToDpn = new SubnetToDpnBuilder().setDpnId(dpId).setKey(new SubnetToDpnKey(dpId)).setVpnInterfaces(
             vpnInterfaces).build();
         allocateIdOutput = new AllocateIdOutputBuilder().setIdValue(longId).build();