Multiple fixes in neutronvpn code 78/40578/22
authorSuraj Ranjan <suraj.ranjan@ericsson.com>
Tue, 21 Jun 2016 04:46:54 +0000 (10:16 +0530)
committerSuraj Ranjan <suraj.ranjan@ericsson.com>
Fri, 1 Jul 2016 14:39:55 +0000 (20:09 +0530)
Commit includes:

1> Fixing NPE in NeutronVpnUtils when no network-type is provided from
northbound

2> NVPN: neutron northbound support for gateway mac for external
networks

3> Use vif_type to determine portname prefix

4> NeutronVPN: Handling fixed-floating IP dissociation for floatingIP
delete

5> NeutronVPN additional -ve validations via ECM for network/router
assc/dissc

  a. Added validations for the following:

  a1) Associate network(s) to vpn:
    i) network already assc to another VPN
    ii) network's subnet added to some router as interface

  a2) Dissociate network(s) from vpn:
    i) network's subnet added to some router as interface

  a3) Associate router to vpn:
    i) router assc to another vpn
    ii) network corresponding to router's subnet interface already assc to VPN

  a4) Dissociate router from vpn:
    i) router assc to another vpn

  b. Updating VPNMaps once assc/dissc are done in assc/dissc network(s) from
     VPN

6> NeutronVPN: adding yang model and notifications for router-dpn
map

  a. Added a container to maintain mapping between neutron router and
  DPN(s) on which vpn-interfaces for router are present.

  b. Added notifications for router associated/dissociated to/from vpn

Change-Id: I30931b4ce6013a4bdc0d58ccc86fa8c83d0cdff6
Signed-off-by: Suraj Ranjan <suraj.ranjan@ericsson.com>
vpnservice/neutronvpn/neutronvpn-api/src/main/java/org/opendaylight/netvirt/neutronvpn/interfaces/INeutronVpnManager.java
vpnservice/neutronvpn/neutronvpn-api/src/main/yang/neutronvpn.yang
vpnservice/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronConstants.java [new file with mode: 0644]
vpnservice/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronFloatingToFixedIpMappingChangeListener.java
vpnservice/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronPortChangeListener.java
vpnservice/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnManager.java
vpnservice/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnNatManager.java
vpnservice/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnProvider.java
vpnservice/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnUtils.java
vpnservice/neutronvpn/neutronvpn-impl/src/test/java/org/opendaylight/netvirt/neutronvpn/NeutronPortChangeListenerTest.java

index 4cb49b432154c6e50053be7fb9930c448b36aa1d..f0cbedaeba6373c6a28d107b18ea974d80544fde 100644 (file)
@@ -31,10 +31,10 @@ public interface INeutronVpnManager {
 
     Subnet getNeutronSubnet(Uuid subnetId);
 
-    String uuidToTapPortName(Uuid id);
-
     Port getNeutronPort(Uuid portId);
 
     IpAddress getNeutronSubnetGateway(Uuid subnetId);
 
+    String getVifPortName(Port port);
+
 }
index 6f0ad09dab1973fd04e23eefaabc867b66ff096a..22fc4ffe96da527df4a07ffd61d5409259416f28 100644 (file)
@@ -163,6 +163,18 @@ module neutronvpn {
         }
     }
 
+    /* container to maintain mapping between neutron router and DPN(s) on which vpn-interfaces for router are present
+    container neutron-router-dpns {
+        list router-dpn-list {
+            key router-id;
+            leaf router-id { type yang:uuid;}
+            list dpn-vpninterfaces-list {
+                key dpn-id;
+                leaf dpn-id { type uint64;}
+                leaf-list vpninterfaces-list { type yang:uuid;}
+            }
+        }
+    }
 
     /* container for DHCP Configuration */
     container dhcp-config {
@@ -404,23 +416,23 @@ module neutronvpn {
     }
 
     notification router-associated-to-vpn {
-                description "router association to vpn";
-                leaf router-id{
-                    type yang:uuid;
-                }
-                leaf vpn-id{
-                    type yang:uuid;
-                }
-        }
+            description "router association to vpn";
+            leaf router-id{
+                type yang:uuid;
+            }
+            leaf vpn-id{
+                type yang:uuid;
+            }
+    }
 
-        notification router-disassociated-from-vpn {
-                description "router disassociation from vpn";
-                leaf router-id{
-                    type yang:uuid;
-                }
-                leaf vpn-id{
-                    type yang:uuid;
-                }
-        }
+    notification router-disassociated-from-vpn {
+            description "router disassociation from vpn";
+            leaf router-id{
+                type yang:uuid;
+            }
+            leaf vpn-id{
+                type yang:uuid;
+            }
+    }
 
 }
diff --git a/vpnservice/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronConstants.java b/vpnservice/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronConstants.java
new file mode 100644 (file)
index 0000000..b84ea1f
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. 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.neutronvpn;
+
+public class NeutronConstants {
+
+    public static final String DEVICE_OWNER_GATEWAY_INF = "network:router_gateway";
+    public static final String DEVICE_OWNER_ROUTER_INF = "network:router_interface";
+    public static final String VNIC_TYPE_NORMAL = "normal";
+    public static final String VIF_TYPE_VHOSTUSER = "vhostuser";
+    public static final String VIF_TYPE_UNBOUND = "unbound";
+    public static final String VIF_TYPE_BINDING_FAILED = "binding_failed";
+    public static final String VIF_TYPE_DISTRIBUTED = "distributed";
+    public static final String VIF_TYPE_OVS = "ovs";
+    public static final String VIF_TYPE_BRIDGE = "bridge";
+    public static final String VIF_TYPE_OTHER = "other";
+    public static final String VIF_TYPE_MACVTAP = "macvtap";
+    public static final String PREFIX_TAP = "tap";
+    public static final String PREFIX_VHOSTUSER = "vhu";
+
+}
index d0ce8be9006f5fb5f548bd38fc1d3080df911b47..93fdc66b2e09e569c656f256b0e888b78953a7dd 100644 (file)
@@ -26,16 +26,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev16011
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports
-        .PortsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports
-        .PortsKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports
-        .ports.IpMapping;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports
-        .ports.IpMappingBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports
-        .ports.IpMappingKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.IpMapping;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.IpMappingBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.IpMappingKey;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
@@ -101,6 +96,11 @@ public class NeutronFloatingToFixedIpMappingChangeListener extends AbstractDataC
         if (LOG.isTraceEnabled()) {
             LOG.trace("Neutron Floating IP deleted : key: " + identifier + ", value=" + input);
         }
+        IpAddress fixedIp = input.getFixedIpAddress();
+        if (fixedIp != null) {
+            clearFromFloatingIpInfo(input.getRouterId().getValue(), input.getPortId().getValue(), fixedIp
+                    .getIpv4Address().getValue());
+        }
     }
 
     // populate the floating to fixed ip map upon association/dissociation from fixed ip
@@ -264,4 +264,77 @@ public class NeutronFloatingToFixedIpMappingChangeListener extends AbstractDataC
             LOG.error("Failed to delete ipMapping from FloatingIpInfo DS for fixed Ip {}", fixedIpAddress);
         }
     }
+
+    protected void dissociatefixedIPFromFloatingIP(String fixedNeutronPortName) {
+        boolean isLockAcquired = false;
+        InstanceIdentifier.InstanceIdentifierBuilder<FloatingIpInfo> floatingIpInfoIdentifierBuilder =
+                InstanceIdentifier.builder(FloatingIpInfo.class);
+        try {
+            Optional<FloatingIpInfo> optionalFloatingIPInfo = NeutronvpnUtils.read(broker, LogicalDatastoreType
+                    .CONFIGURATION, floatingIpInfoIdentifierBuilder.build());
+            if (optionalFloatingIPInfo.isPresent() && optionalFloatingIPInfo.get() != null) {
+                List<RouterPorts> routerPortsList = optionalFloatingIPInfo.get().getRouterPorts();
+                if (routerPortsList != null && !routerPortsList.isEmpty()) {
+                    for (RouterPorts routerPorts : routerPortsList) {
+                        List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating
+                                .ip.info.router.ports.Ports> portsList = routerPorts.getPorts();
+                        if (portsList != null && !portsList.isEmpty()) {
+                            String routerName = routerPorts.getRouterId();
+                            InstanceIdentifier.InstanceIdentifierBuilder<RouterPorts> routerPortsIdentifierBuilder =
+                                    floatingIpInfoIdentifierBuilder.child(RouterPorts.class, new RouterPortsKey
+                                            (routerName));
+                            if (portsList.size() == 1) {
+                                try {
+                                    // remove entire routerPorts node
+                                    isLockAcquired = NeutronvpnUtils.lock(lockManager, routerName);
+                                    //Fixme :planning to use synchronized blocks for entire NeutronVPN module instead
+                                    // of using this lockmanager timed API.
+                                    LOG.debug("removing routerPorts node: {} ", routerName);
+                                    MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, routerPortsIdentifierBuilder.build());
+
+                                } catch (Exception e) {
+                                    LOG.error("Failure in deletion of routerPorts node {}", routerName);
+                                } finally {
+                                    if (isLockAcquired) {
+                                        NeutronvpnUtils.unlock(lockManager, routerName);
+                                    }
+                                }
+                            } else {
+                                InstanceIdentifier.InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn
+                                        .opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports
+                                        .Ports> portsIdentifierBuilder = routerPortsIdentifierBuilder.child(org
+                                        .opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
+                                        .floating.ip.info.router.ports.Ports.class, new PortsKey(fixedNeutronPortName));
+                                try {
+                                    // remove entire ports node under this routerPorts node
+                                    isLockAcquired = NeutronvpnUtils.lock(lockManager, fixedNeutronPortName);
+                                    LOG.debug("removing ports node {} under routerPorts node {}",
+                                            fixedNeutronPortName, routerName);
+                                    MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION,
+                                            portsIdentifierBuilder.build());
+                                } catch (Exception e) {
+                                    LOG.error("Failure in deletion of routerPorts node {}", routerName);
+                                } finally {
+                                    if (isLockAcquired) {
+                                        NeutronvpnUtils.unlock(lockManager, routerName);
+                                    }
+                                }
+                            }
+                            LOG.debug("Deletion from FloatingIpInfo DS successful for fixedIP neutron port {} ",
+                                    fixedNeutronPortName);
+                        } else {
+                            LOG.debug("Neutron port {} not associated to any floating IP", fixedNeutronPortName);
+                        }
+                    }
+                } else {
+                    LOG.debug("No router present containing fixed to floating IP association(s)");
+                }
+            } else {
+                LOG.debug("FloatingIPInfo DS empty. Hence, no router present containing fixed to floating IP " +
+                        "association(s)");
+            }
+        } catch (Exception e) {
+            LOG.error("Failed to dissociate fixedIP from FloatingIpInfo DS for neutron port {}", fixedNeutronPortName);
+        }
+    }
 }
index 2f485624a718531c0652ba8fd39f19e3385e0cf5..19bc91f0830d8885fce35899876349fff5d7ddc3 100644 (file)
@@ -26,6 +26,10 @@ 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.InterfaceKey;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
 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.rev160111.FloatingIpInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
 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;
@@ -67,16 +71,19 @@ public class NeutronPortChangeListener extends AbstractDataChangeListener<Port>
     private LockManagerService lockManager;
     private NotificationPublishService notificationPublishService;
     private NotificationService notificationService;
+    private NeutronFloatingToFixedIpMappingChangeListener floatingIpMapListener;
 
 
     public NeutronPortChangeListener(final DataBroker db, NeutronvpnManager nVpnMgr,NeutronvpnNatManager nVpnNatMgr,
-                                     NotificationPublishService notiPublishService, NotificationService notiService) {
+                                     NotificationPublishService notiPublishService, NotificationService notiService,
+                                     NeutronFloatingToFixedIpMappingChangeListener neutronFloatingToFixedIpMappingChangeListener) {
         super(Port.class);
         broker = db;
         nvpnManager = nVpnMgr;
         nvpnNatManager = nVpnNatMgr;
         notificationPublishService = notiPublishService;
         notificationService = notiService;
+        floatingIpMapListener = neutronFloatingToFixedIpMappingChangeListener;
         registerListener(db);
     }
 
@@ -123,7 +130,7 @@ public class NeutronPortChangeListener extends AbstractDataChangeListener<Port>
         }
         /* check if router interface has been created */
         if ((input.getDeviceOwner() != null) && (input.getDeviceId() != null)) {
-            if (input.getDeviceOwner().equals(NeutronvpnUtils.DEVICE_OWNER_ROUTER_INF)) {
+            if (input.getDeviceOwner().equals(NeutronConstants.DEVICE_OWNER_ROUTER_INF)) {
                 handleRouterInterfaceAdded(input);
                 /* nothing else to do here */
                 return;
@@ -147,7 +154,7 @@ public class NeutronPortChangeListener extends AbstractDataChangeListener<Port>
             return;
         }
         if ((input.getDeviceOwner() != null) && (input.getDeviceId() != null)) {
-            if (input.getDeviceOwner().equals(NeutronvpnUtils.DEVICE_OWNER_ROUTER_INF)) {
+            if (input.getDeviceOwner().equals(NeutronConstants.DEVICE_OWNER_ROUTER_INF)) {
                 handleRouterInterfaceRemoved(input);
                 /* nothing else to do here */
                 return;
@@ -173,9 +180,14 @@ public class NeutronPortChangeListener extends AbstractDataChangeListener<Port>
         List<FixedIps> oldIPs = (original.getFixedIps() != null) ? original.getFixedIps() : new ArrayList<FixedIps>();
         List<FixedIps> newIPs = (update.getFixedIps() != null) ? update.getFixedIps() : new ArrayList<FixedIps>();
 
+        /* check if VIF type updated as part of port binding */
+        if (NeutronvpnUtils.isPortVifTypeUpdated(original, update)) {
+            updateOfPortInterface(original, update);
+        }
+
         /* check if router interface has been updated */
         if ((update.getDeviceOwner() != null) && (update.getDeviceId() != null)) {
-            if (update.getDeviceOwner().equals(NeutronvpnUtils.DEVICE_OWNER_ROUTER_INF)) {
+            if (update.getDeviceOwner().equals(NeutronConstants.DEVICE_OWNER_ROUTER_INF)) {
                 handleRouterInterfaceAdded(update);
                 /* nothing else to do here */
                 return;
@@ -214,8 +226,8 @@ public class NeutronPortChangeListener extends AbstractDataChangeListener<Port>
                     }
                 }
             } else {
-                LOG.error("Neutron network {} corresponding to router interface port {} for neutron router {} already" +
-                        " associated to VPN {}", infNetworkId.getValue(), routerPort.getUuid().getValue(), routerId
+                LOG.warn("Neutron network {} corresponding to router interface port {} for neutron router {} already " +
+                        "associated to VPN {}", infNetworkId.getValue(), routerPort.getUuid().getValue(), routerId
                         .getValue(), existingVpnId.getValue());
             }
         }
@@ -264,7 +276,8 @@ public class NeutronPortChangeListener extends AbstractDataChangeListener<Port>
     }
 
     private void handleNeutronPortDeleted(Port port) {
-        LOG.debug("Of-port-interface removal");
+        //dissociate fixedIP from floatingIP if associated
+        floatingIpMapListener.dissociatefixedIPFromFloatingIP(port.getUuid().getValue());
         LOG.debug("Remove port from subnet");
         // remove port from local Subnets DS
         Uuid vpnId = removePortFromSubnets(port);
@@ -276,6 +289,7 @@ public class NeutronPortChangeListener extends AbstractDataChangeListener<Port>
         }
         // Remove of-port interface for this neutron port
         // ELAN interface is also implicitly deleted as part of this operation
+        LOG.debug("Of-port-interface removal", port);
         deleteOfPortInterface(port);
 
         Uuid routerId = NeutronvpnUtils.getVpnMap(broker, vpnId).getRouterId();
@@ -405,15 +419,17 @@ public class NeutronPortChangeListener extends AbstractDataChangeListener<Port>
     }
 
     private Interface createInterface(Port port) {
-        String parentRefName = NeutronvpnUtils.uuidToTapPortName(port.getUuid());
+
+        String parentRefName = NeutronvpnUtils.getVifPortName(port);
         String interfaceName = port.getUuid().getValue();
         IfL2vlan.L2vlanMode l2VlanMode = IfL2vlan.L2vlanMode.Trunk;
         InterfaceBuilder interfaceBuilder = new InterfaceBuilder();
         IfL2vlanBuilder ifL2vlanBuilder = new IfL2vlanBuilder();
         ifL2vlanBuilder.setL2vlanMode(l2VlanMode);
-        ParentRefsBuilder parentRefsBuilder = new ParentRefsBuilder().setParentInterface(parentRefName);
-        interfaceBuilder.setEnabled(true).setName(interfaceName).setType(L2vlan.class).addAugmentation(IfL2vlan
-                .class, ifL2vlanBuilder.build()).addAugmentation(ParentRefs.class, parentRefsBuilder.build());
+        if (parentRefName != null) {
+            ParentRefsBuilder parentRefsBuilder = new ParentRefsBuilder().setParentInterface(parentRefName);
+            interfaceBuilder.addAugmentation(ParentRefs.class, parentRefsBuilder.build());
+        }
 
         if (NeutronvpnUtils.isPortSecurityEnabled(port)) {
             InterfaceAclBuilder interfaceAclBuilder = new InterfaceAclBuilder();
@@ -425,6 +441,8 @@ public class NeutronPortChangeListener extends AbstractDataChangeListener<Port>
             interfaceBuilder.addAugmentation(InterfaceAcl.class, interfaceAclBuilder.build());
         }
 
+        interfaceBuilder.setEnabled(true).setName(interfaceName).setType(L2vlan.class)
+                .addAugmentation(IfL2vlan.class, ifL2vlanBuilder.build());
         return interfaceBuilder.build();
     }
 
@@ -445,6 +463,41 @@ public class NeutronPortChangeListener extends AbstractDataChangeListener<Port>
         }
     }
 
+    private Interface updateInterface(Port original, Port update) {
+        String parentRefName = NeutronvpnUtils.getVifPortName(update);
+        String interfaceName = original.getUuid().getValue();
+        InterfaceBuilder interfaceBuilder = new InterfaceBuilder();
+
+        if (parentRefName != null) {
+            ParentRefsBuilder parentRefsBuilder = new ParentRefsBuilder().setParentInterface(parentRefName);
+            interfaceBuilder.addAugmentation(ParentRefs.class, parentRefsBuilder.build());
+        }
+
+        interfaceBuilder.setName(interfaceName);
+        return interfaceBuilder.build();
+    }
+
+    private String updateOfPortInterface(Port original, Port updated) {
+        Interface inf = updateInterface(original, updated);
+        String infName = inf.getName();
+
+        LOG.debug("Updating OFPort Interface {}", infName);
+        InstanceIdentifier interfaceIdentifier = NeutronvpnUtils.buildVlanInterfaceIdentifier(infName);
+        try {
+            Optional<Interface> optionalInf = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
+                    interfaceIdentifier);
+            if (optionalInf.isPresent()) {
+                MDSALUtil.syncUpdate(broker, LogicalDatastoreType.CONFIGURATION, interfaceIdentifier, inf);
+            } else {
+                LOG.error("Interface {} doesn't exist", infName);
+            }
+        } catch (Exception e) {
+            LOG.error("failed to update interface {} due to the exception {} ", infName, e);
+        }
+
+        return infName;
+    }
+
     private void createElanInterface(Port port, String name) {
         String elanInstanceName = port.getNetworkId().getValue();
         List<PhysAddress> physAddresses = new ArrayList<>();
index 737e97308d2319fb1b32e5bd4373e5dc68b2bb17..a3c09d553e2b190d298c855027145804511ee93c 100644 (file)
@@ -825,8 +825,11 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
         boolean isLockAcquired = false;
         String lockName = vpnId.getValue() + subnet.getValue();
         String elanInstanceName = sn.getNetworkId().getValue();
-        InstanceIdentifier<ElanInstance>elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class).child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
-        Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION, elanIdentifierId);
+        InstanceIdentifier<ElanInstance> elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class).child
+                (ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
+        Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
+                elanIdentifierId);
+        //TODO: Cache it in add so can reuse it in update and delete. Best would be to cache in some ElanUtils
         long elanTag = elanInstance.get().getElanTag();
         Uuid routerId = NeutronvpnUtils.getVpnMap(broker, vpnId).getRouterId();
         if (vpnId.equals(routerId)) {
@@ -861,15 +864,18 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
         boolean isLockAcquired = false;
         String lockName = vpnId.getValue() + subnet.getValue();
         String elanInstanceName = sn.getNetworkId().getValue();
-        InstanceIdentifier<ElanInstance>elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class).child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
-        Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION, elanIdentifierId);
+        InstanceIdentifier<ElanInstance> elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class).child
+                (ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
+        Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
+                elanIdentifierId);
         long elanTag = elanInstance.get().getElanTag();
         try {
             isLockAcquired = NeutronvpnUtils.lock(lockManager, lockName);
-            checkAndPublishSubnetUpdNotification(subnet, sn.getSubnetIp(), vpnId.getValue(), isBeingAssociated, elanTag);
+            checkAndPublishSubnetUpdNotification(subnet, sn.getSubnetIp(), vpnId.getValue(), isBeingAssociated,
+                    elanTag);
             logger.debug("Subnet updated in Vpn notification sent");
-        }catch (Exception e){
-            logger.error("Subnet updated in Vpn notification failed",e);
+        } catch (Exception e) {
+            logger.error("Subnet updated in Vpn notification failed", e);
         }finally {
             if (isLockAcquired) {
                 NeutronvpnUtils.unlock(lockManager, lockName);
@@ -1036,8 +1042,10 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
         boolean isLockAcquired = false;
         String lockName = vpnId.getValue() + subnet.getValue();
         String elanInstanceName = sn.getNetworkId().getValue();
-        InstanceIdentifier<ElanInstance>elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class).child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
-        Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION, elanIdentifierId);
+        InstanceIdentifier<ElanInstance> elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class).child
+                (ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
+        Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
+                elanIdentifierId);
         long elanTag = elanInstance.get().getElanTag();
         Uuid routerId = NeutronvpnUtils.getVpnMap(broker, vpnId).getRouterId();
         if (vpnId.equals(routerId)) {
@@ -1106,57 +1114,80 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
     }
 
     protected List<String> associateNetworksToVpn(Uuid vpn, List<Uuid> networks) {
-        List<String> failed = new ArrayList<>();
+
+        List<String> failedNwList = new ArrayList<String>();
+        List<Uuid> passedNwList = new ArrayList<>();
         if (!networks.isEmpty()) {
-            // store in Data Base
-            updateVpnMaps(vpn, null, null, null, networks);
             // process corresponding subnets for VPN
             for (Uuid nw : networks) {
-                Network net = NeutronvpnUtils.getNeutronNetwork(broker, nw);
-                if (net == null) {
-                    failed.add(nw.getValue());
+                Network network = NeutronvpnUtils.getNeutronNetwork(broker, nw);
+                Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(broker, nw);
+                if (network == null) {
+                    failedNwList.add(String.format("network %s not found", nw.getValue()));
+                } else if (vpnId != null) {
+                    failedNwList.add(String.format("network %s already associated to another VPN %s", nw.getValue(),
+                            vpnId.getValue()));
                 } else {
                     List<Uuid> networkSubnets = NeutronvpnUtils.getSubnetIdsFromNetworkId(broker, nw);
-                    logger.debug("Adding network subnets...");
+                    logger.debug("Adding network subnets...{}", networkSubnets);
                     if (networkSubnets != null) {
                         for (Uuid subnet : networkSubnets) {
-                            addSubnetToVpn(vpn, subnet);
+                            // check if subnet added as router interface to some router
+                            Uuid routerVpnId = NeutronvpnUtils.getVpnForSubnet(broker, subnet);
+                            if (routerVpnId == null) {
+                                addSubnetToVpn(vpn, subnet);
+                                passedNwList.add(nw);
+                            } else {
+                                failedNwList.add(String.format("subnet %s already added as router interface bound to " +
+                                        "internal/external VPN %s", subnet.getValue (), routerVpnId.getValue()));
+                            }
                         }
                     }
-                    if (net.getAugmentation(NetworkL3Extension.class).isExternal()) {
-                        nvpnNatManager.addExternalNetworkToVpn(net, vpn);
+                    if (network.getAugmentation(NetworkL3Extension.class) != null && network.getAugmentation
+                            (NetworkL3Extension.class).isExternal()) {
+                        nvpnNatManager.addExternalNetworkToVpn(network, vpn);
                     }
                 }
             }
+            updateVpnMaps(vpn, null, null, null, passedNwList);
         }
-        return failed;
+        return failedNwList;
     }
 
     protected List<String> dissociateNetworksFromVpn(Uuid vpn, List<Uuid> networks) {
-        List<String> failed = new ArrayList<>();
+
+        List<String> failedNwList = new ArrayList<String>();
+        List<Uuid> passedNwList = new ArrayList<>();
         if (networks != null && !networks.isEmpty()) {
-            // store in Data Base
-            clearFromVpnMaps(vpn, null, networks);
             // process corresponding subnets for VPN
             for (Uuid nw : networks) {
-                Network net = NeutronvpnUtils.getNeutronNetwork(broker, nw);
-                if (net == null) {
-                    failed.add(nw.getValue());
+                Network network = NeutronvpnUtils.getNeutronNetwork(broker, nw);
+                if (network == null) {
+                    failedNwList.add(String.format("network %s not found", nw.getValue()));
                 } else {
                     List<Uuid> networkSubnets = NeutronvpnUtils.getSubnetIdsFromNetworkId(broker, nw);
                     logger.debug("Removing network subnets...");
                     if (networkSubnets != null) {
                         for (Uuid subnet : networkSubnets) {
-                            removeSubnetFromVpn(vpn, subnet);
+                            // check if subnet added as router interface to some router
+                            Uuid routerVpnId = NeutronvpnUtils.getVpnForSubnet(broker, subnet);
+                            if (routerVpnId == null) {
+                                removeSubnetFromVpn(vpn, subnet);
+                                passedNwList.add(nw);
+                            } else {
+                                failedNwList.add(String.format("subnet %s added as router interface bound to " +
+                                        "internal/external VPN %s", subnet.getValue (), routerVpnId.getValue()));
+                            }
                         }
                     }
-                    if (net.getAugmentation(NetworkL3Extension.class).isExternal()) {
-                        nvpnNatManager.removeExternalNetworkFromVpn(net);
+                    if (network.getAugmentation(NetworkL3Extension.class).isExternal()) {
+                        nvpnNatManager.removeExternalNetworkFromVpn(network);
                     }
                 }
             }
+            clearFromVpnMaps(vpn, null, passedNwList);
         }
-        return failed;
+        return failedNwList;
     }
 
     @Override
@@ -1174,7 +1205,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
                 if (netIds != null && !netIds.isEmpty()) {
                     List<String> failed = associateNetworksToVpn(vpnId, netIds);
                     if (!failed.isEmpty()) {
-                        returnMsg.append("network(s) not found : ").append(failed);
+                        returnMsg.append(failed);
                     }
                 }
             } else {
@@ -1215,9 +1246,13 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
                 Router rtr = NeutronvpnUtils.getNeutronRouter(broker, routerId);
                 VpnMap vpnMap = NeutronvpnUtils.getVpnMap(broker, vpnId);
                 if (rtr != null && vpnMap != null) {
+                    Uuid extVpnId = NeutronvpnUtils.getVpnForRouter(broker, routerId, true);
                     if (vpnMap.getRouterId() != null) {
                         returnMsg.append("vpn ").append(vpnId.getValue()).append(" already associated to router ")
                                 .append(vpnMap.getRouterId().getValue());
+                    } else if (extVpnId != null) {
+                        returnMsg.append("router ").append(routerId.getValue()).append(" already associated to " +
+                                "another VPN ").append(extVpnId.getValue());
                     } else {
                         associateRouterToVpn(vpnId, routerId);
                     }
@@ -1262,7 +1297,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
                 if (netIds != null && !netIds.isEmpty()) {
                     List<String> failed = dissociateNetworksFromVpn(vpnId, netIds);
                     if (!failed.isEmpty()) {
-                        returnMsg.append("netowrk(s) not found : ").append(failed);
+                        returnMsg.append(failed);
                     }
                 }
             } else {
@@ -1304,7 +1339,13 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
                 if (routerId != null) {
                     Router rtr = NeutronvpnUtils.getNeutronRouter(broker, routerId);
                     if (rtr != null) {
-                        dissociateRouterFromVpn(vpnId, routerId);
+                        Uuid routerVpnId = NeutronvpnUtils.getVpnForRouter(broker, routerId, true);
+                        if (!routerVpnId.equals(vpnId)) {
+                            returnMsg.append("input router ").append(routerId.getValue()).append(" associated to " +
+                                    "vpn ").append(routerVpnId.getValue()).append("instead of the vpn given as input");
+                        } else {
+                            dissociateRouterFromVpn(vpnId, routerId);
+                        }
                     } else {
                         returnMsg.append("router not found : ").append(routerId.getValue());
                     }
@@ -1441,11 +1482,12 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
         try {
             Optional<Ports> ports = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION, portidentifier);
             if (ports.isPresent() && ports.get().getPort() != null) {
-                List<Port> portList = ports.get().getPort();
-                for (Port port : portList) {
-                    result.add(String.format(" %-34s  %-22s  %-22s  %-6s ", port.getUuid().getValue(), port
-                            .getMacAddress(), port.getFixedIps().get(0).getIpAddress().getIpv4Address().getValue(),
-                            NeutronvpnUtils.getIPPrefixFromPort(broker, port)));
+                for (Port port : ports.get().getPort()) {
+                    if (port.getFixedIps() != null && !port.getFixedIps().isEmpty()) {
+                        result.add(String.format(" %-34s  %-22s  %-22s  %-6s ", port.getUuid().getValue(), port.
+                                getMacAddress(), port.getFixedIps().get(0).getIpAddress().getIpv4Address().getValue(),
+                                NeutronvpnUtils.getIPPrefixFromPort(broker, port)));
+                    }
                 }
             }
         } catch (Exception e) {
@@ -1528,7 +1570,8 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
         return help.toString();
     }
 
-    private void checkAndPublishSubnetAddNotification(Uuid subnetId, String subnetIp, String vpnName, Boolean isExternalvpn, Long elanTag)throws InterruptedException{
+    private void checkAndPublishSubnetAddNotification(Uuid subnetId, String subnetIp, String vpnName,
+                                                      Boolean isExternalvpn, Long elanTag)throws InterruptedException {
         SubnetAddedToVpnBuilder builder = new SubnetAddedToVpnBuilder();
 
         logger.info("publish notification called");
@@ -1542,7 +1585,8 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
         notificationPublishService.putNotification(builder.build());
     }
 
-    private void checkAndPublishSubnetDelNotification(Uuid subnetId, String subnetIp, String vpnName, Boolean isExternalvpn, Long elanTag)throws InterruptedException{
+    private void checkAndPublishSubnetDelNotification(Uuid subnetId, String subnetIp, String vpnName,
+                                                      Boolean isExternalvpn, Long elanTag) throws InterruptedException {
         SubnetDeletedFromVpnBuilder builder = new SubnetDeletedFromVpnBuilder();
 
         logger.info("publish notification called");
@@ -1556,7 +1600,8 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
         notificationPublishService.putNotification(builder.build());
     }
 
-    private void checkAndPublishSubnetUpdNotification(Uuid subnetId, String subnetIp, String vpnName, Boolean isExternalvpn, Long elanTag)throws InterruptedException{
+    private void checkAndPublishSubnetUpdNotification(Uuid subnetId, String subnetIp, String vpnName,
+                                                      Boolean isExternalvpn, Long elanTag) throws InterruptedException {
         SubnetUpdatedInVpnBuilder builder = new SubnetUpdatedInVpnBuilder();
 
         logger.info("publish notification called");
index 41f78d2e374b077ddab735cbd4a0838ea221bdc0..1508921c26139afb0fbcfc5ef270d62d05a49a44 100644 (file)
@@ -24,6 +24,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev16011
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
+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;
 import org.slf4j.LoggerFactory;
@@ -81,6 +82,7 @@ public class NeutronvpnNatManager implements AutoCloseable {
                 logger.trace("External Network removal detected " +
                         "for router " +  routerId.getValue());
                 removeExternalNetworkFromRouter(origExtNetId, update);
+                //gateway mac unset handled as part of gateway clear deleting top-level routers node
                 return;
             }
             origExtNetId = original.getExternalGatewayInfo().getExternalNetworkId();
@@ -412,12 +414,12 @@ public class NeutronvpnNatManager implements AutoCloseable {
     private void addExternalRouter(Router update, DataBroker broker) {
         Uuid routerId = update.getUuid();
         Uuid extNetId = update.getExternalGatewayInfo().getExternalNetworkId();
+        Uuid gatewayPortId = update.getGatewayPortId();
 
         // Create and add Routers object for this Router to the ExtRouters list
 
         // Create a Routers object
-        InstanceIdentifier<Routers> routersIdentifier = InstanceIdentifier.builder(ExtRouters.class).
-                child(Routers.class, new RoutersKey(routerId.getValue())).build();
+        InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
 
         try {
             Optional<Routers> optionalRouters = NeutronvpnUtils.read(broker,
@@ -446,6 +448,13 @@ public class NeutronvpnNatManager implements AutoCloseable {
                 }
                 builder.setExternalIps(ext_fixed_ips);
             }
+            if (gatewayPortId != null) {
+                logger.trace("Setting/Updating gateway Mac for router {}", routerId.getValue());
+                Port port = NeutronvpnUtils.getNeutronPort(broker, gatewayPortId);
+                if (port.getDeviceOwner().equals(NeutronConstants.DEVICE_OWNER_GATEWAY_INF)) {
+                    builder.setExtGwMacAddress(port.getMacAddress().getValue());
+                }
+            }
             List<Uuid> subList = NeutronvpnUtils.getNeutronRouterSubnetIds(broker, routerId);
             builder.setSubnetIds(subList);
             Routers routerss = builder.build();
@@ -467,8 +476,7 @@ public class NeutronvpnNatManager implements AutoCloseable {
     private void removeExternalRouter(Uuid extNetId, Router update, DataBroker broker) {
         Uuid routerId = update.getUuid();
 
-        InstanceIdentifier<Routers> routersIdentifier = InstanceIdentifier.builder(ExtRouters.class).
-                child(Routers.class, new RoutersKey(routerId.getValue())).build();
+        InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
 
         try {
             Optional<Routers> optionalRouters = NeutronvpnUtils.read(broker,
@@ -494,8 +502,7 @@ public class NeutronvpnNatManager implements AutoCloseable {
     private void handleExternalFixedIpsForRouter(Router update, DataBroker broker) {
         Uuid routerId = update.getUuid();
 
-        InstanceIdentifier<Routers> routersIdentifier = InstanceIdentifier.builder(ExtRouters.class).
-                child(Routers.class, new RoutersKey(routerId.getValue())).build();
+        InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
 
         try {
             Optional<Routers> optionalRouters = NeutronvpnUtils.read(broker,
@@ -528,8 +535,7 @@ public class NeutronvpnNatManager implements AutoCloseable {
 
     public void handleSubnetsForExternalRouter(Uuid routerId, DataBroker broker) {
 
-        InstanceIdentifier<Routers> routersIdentifier = InstanceIdentifier.builder(ExtRouters.class).
-                child(Routers.class, new RoutersKey(routerId.getValue())).build();
+        InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
 
         try {
             Optional<Routers> optionalRouters = NeutronvpnUtils.read(broker,
@@ -565,8 +571,7 @@ public class NeutronvpnNatManager implements AutoCloseable {
     private void handleSnatSettingChangeForRouter(Router update, DataBroker broker) {
         Uuid routerId = update.getUuid();
 
-        InstanceIdentifier<Routers> routersIdentifier = InstanceIdentifier.builder(ExtRouters.class).
-                child(Routers.class, new RoutersKey(routerId.getValue())).build();
+        InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
 
         try {
             Optional<Routers> optionalRouters = NeutronvpnUtils.read(broker,
index 4e4d6c297374877dbba7a7ff54a9404226154dd1..8fb302db3b7b9b8fa681debaf2d97abc11bca1da 100644 (file)
@@ -47,7 +47,6 @@ public class NeutronvpnProvider implements BindingAwareProvider, INeutronVpnMana
     private NotificationPublishService notificationPublishService;
     private NotificationService notificationService;
     private EntityOwnershipService entityOwnershipService;
-    private DataBroker broker;
 
     public NeutronvpnProvider(RpcProviderRegistry rpcRegistry,NotificationPublishService notificationPublishService,
                               NotificationService notificationService) {
@@ -90,7 +89,7 @@ public class NeutronvpnProvider implements BindingAwareProvider, INeutronVpnMana
             subnetListener = new NeutronSubnetChangeListener(dbx, nvManager);
             routerListener = new NeutronRouterChangeListener(dbx, nvManager, nvNatManager);
             portListener = new NeutronPortChangeListener(dbx, nvManager, nvNatManager,
-                    notificationPublishService,notificationService);
+                    notificationPublishService,notificationService, floatingIpMapListener);
             portListener.setLockManager(lockManager);
             portListener.setLockManager(lockManager);
             floatingIpMapListener = new NeutronFloatingToFixedIpMappingChangeListener(dbx);
@@ -155,12 +154,12 @@ public class NeutronvpnProvider implements BindingAwareProvider, INeutronVpnMana
 
     @Override
     public Subnet getNeutronSubnet(Uuid subnetId) {
-        return NeutronvpnUtils.getNeutronSubnet(broker, subnetId);
+        return nvManager.getNeutronSubnet(subnetId);
     }
 
     @Override
-    public String uuidToTapPortName(Uuid id) {
-        return NeutronvpnUtils.uuidToTapPortName(id);
+    public String getVifPortName(Port port) {
+        return NeutronvpnUtils.getVifPortName(port);
     }
 
     @Override
index fb7db64ab2a38fc0442732d3e35cdd34e6217e3b..e280a5278a26e299407a0d70cc96c96a3067e2c1 100644 (file)
@@ -20,6 +20,9 @@ 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.Interface;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
 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.rev160111.ExtRouters;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.binding.rev150712.PortBindingExtension;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.Routers;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.RouterKey;
@@ -74,8 +77,6 @@ import java.util.concurrent.Future;
 public class NeutronvpnUtils {
 
     private static final Logger logger = LoggerFactory.getLogger(NeutronvpnUtils.class);
-    public static final String DEVICE_OWNER_ROUTER_INF = "network:router_interface";
-    public static final String VNIC_TYPE_NORMAL = "normal";
     public static ConcurrentHashMap<Uuid, Network> networkMap = new ConcurrentHashMap<Uuid, Network>();
     public static ConcurrentHashMap<Uuid, Router> routerMap = new ConcurrentHashMap<Uuid, Router>();
     public static ConcurrentHashMap<Uuid, Port> portMap = new ConcurrentHashMap<Uuid, Port>();
@@ -121,7 +122,16 @@ public class NeutronvpnUtils {
         return null;
     }
 
-    // true for external vpn, false for internal vpn
+    protected static Uuid getVpnForSubnet(DataBroker broker, Uuid subnetId) {
+        InstanceIdentifier<Subnetmap> subnetmapIdentifier = buildSubnetMapIdentifier(subnetId);
+        Optional<Subnetmap> optionalSubnetMap = read(broker, LogicalDatastoreType.CONFIGURATION, subnetmapIdentifier);
+        if (optionalSubnetMap.isPresent()) {
+            return optionalSubnetMap.get().getVpnId();
+        }
+        return null;
+    }
+
+    // @param external vpn - true if external vpn being fetched, false for internal vpn
     protected static Uuid getVpnForRouter(DataBroker broker, Uuid routerId, Boolean externalVpn) {
         InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
         Optional<VpnMaps> optionalVpnMaps = read(broker, LogicalDatastoreType.CONFIGURATION,
@@ -216,7 +226,7 @@ public class NeutronvpnUtils {
         if (ports != null && ports.getPort() != null) {
             for (Port port: ports.getPort()) {
                 if ((port.getDeviceOwner() != null) && (port.getDeviceId() != null)) {
-                    if (port.getDeviceOwner().equals(DEVICE_OWNER_ROUTER_INF) &&
+                    if (port.getDeviceOwner().equals(NeutronConstants.DEVICE_OWNER_ROUTER_INF) &&
                             port.getDeviceId().equals(routerId.getValue())) {
                         for (FixedIps portIp: port.getFixedIps()) {
                             subnetIdList.add(portIp.getSubnetId());
@@ -310,9 +320,43 @@ public class NeutronvpnUtils {
         return subnet;
     }
 
-    protected static String uuidToTapPortName(Uuid id) {
-        String tapId = id.getValue().substring(0, 11);
-        return new StringBuilder().append("tap").append(tapId).toString();
+    protected static String getVifPortName(Port port) {
+        if (port == null || port.getUuid() == null) {
+            logger.warn("Invalid Neutron port {}", port);
+            return null;
+        }
+        String tapId = port.getUuid().getValue().substring(0, 11);
+        String portNamePrefix = getPortNamePrefix(port);
+        if (portNamePrefix != null) {
+            return new StringBuilder().append(portNamePrefix).append(tapId).toString();
+        }
+        logger.debug("Failed to get prefix for port {}", port.getUuid());
+        return null;
+    }
+
+    protected static String getPortNamePrefix(Port port) {
+        PortBindingExtension portBinding = port.getAugmentation(PortBindingExtension.class);
+        if (portBinding == null || portBinding.getVifType() == null) {
+            return null;
+        }
+        switch(portBinding.getVifType()) {
+            case NeutronConstants.VIF_TYPE_VHOSTUSER:
+                return NeutronConstants.PREFIX_VHOSTUSER;
+            case NeutronConstants.VIF_TYPE_OVS:
+            case NeutronConstants.VIF_TYPE_DISTRIBUTED:
+            case NeutronConstants.VIF_TYPE_BRIDGE:
+            case NeutronConstants.VIF_TYPE_OTHER:
+            case NeutronConstants.VIF_TYPE_MACVTAP:
+                return NeutronConstants.PREFIX_TAP;
+            case NeutronConstants.VIF_TYPE_UNBOUND:
+            case NeutronConstants.VIF_TYPE_BINDING_FAILED:
+            default:
+                return null;
+        }
+    }
+
+    protected static boolean isPortVifTypeUpdated(Port original, Port updated) {
+        return ((getPortNamePrefix(original) == null) && (getPortNamePrefix(updated) != null));
     }
 
     protected static boolean lock(LockManagerService lockManager, String lockName) {
@@ -445,6 +489,15 @@ public class NeutronvpnUtils {
         return id;
     }
 
+    static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext
+            .routers.Routers> buildExtRoutersIdentifier(Uuid routerId) {
+        InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers
+                .Routers> id = InstanceIdentifier.builder(ExtRouters.class).child(org.opendaylight.yang.gen.v1.urn
+                .opendaylight.netvirt.natservice.rev160111.ext.routers.Routers.class,
+                new RoutersKey(routerId.getValue())).build();
+        return id;
+    }
+
     static <T extends DataObject> Optional<T> read(DataBroker broker, LogicalDatastoreType datastoreType,
                                                    InstanceIdentifier<T> path) {
 
@@ -462,10 +515,10 @@ public class NeutronvpnUtils {
 
     static boolean isNetworkTypeVlanOrGre(Network network) {
         NetworkProviderExtension npe = network.getAugmentation(NetworkProviderExtension.class);
-        if (npe != null) {
-            Class<? extends NetworkTypeBase> networkTypeBase = npe.getNetworkType();
-            if (networkTypeBase.isAssignableFrom(NetworkTypeVlan.class) || networkTypeBase.isAssignableFrom(NetworkTypeGre.class)) {
-                logger.trace("Network is of type {}", networkTypeBase);
+        if (npe != null && npe.getNetworkType() != null) {
+            if (npe.getNetworkType().isAssignableFrom(NetworkTypeVlan.class) ||
+                    npe.getNetworkType().isAssignableFrom(NetworkTypeGre.class)) {
+                logger.trace("Network is of type {}", npe.getNetworkType());
                 return true;
             }
         }
index 0a2de6231b20cb579fe32de7460d4e6a4de99e9f..306f2fe12bf2c36d5f5f713389528ea7cbe1a5e7 100644 (file)
@@ -52,6 +52,8 @@ public class NeutronPortChangeListenerTest {
     @Mock
     NotificationService notiService;
     @Mock
+    NeutronFloatingToFixedIpMappingChangeListener floatingIpMapListener;
+    @Mock
     ListenerRegistration<DataChangeListener> dataChangeListenerRegistration;
     @Mock
     WriteTransaction mockWriteTx;
@@ -73,7 +75,8 @@ public class NeutronPortChangeListenerTest {
         when(mockReadTx.read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class))).
             thenReturn(Futures.immediateCheckedFuture(Optional.of(mockNetwork)));
 
-        neutronPortChangeListener = new NeutronPortChangeListener(dataBroker, nVpnMgr, nVpnNatMgr, notiPublishService, notiService);
+        neutronPortChangeListener = new NeutronPortChangeListener(dataBroker, nVpnMgr, nVpnNatMgr,
+                notiPublishService, notiService, floatingIpMapListener);
     }
 
     @Test