Create ELAN interface for physnet ports 51/41751/29
authorTali <tali.ben-meir@hpe.com>
Wed, 13 Jul 2016 09:00:31 +0000 (12:00 +0300)
committerSam Hague <shague@redhat.com>
Sat, 30 Jul 2016 12:54:59 +0000 (12:54 +0000)
Change-Id: Ibafba16bb2dac1490d711532edafc305173d72a3
Signed-off-by: Tali <tali.ben-meir@hpe.com>
vpnservice/elanmanager/elanmanager-api/src/main/java/org/opendaylight/netvirt/elanmanager/api/IElanService.java
vpnservice/elanmanager/elanmanager-api/src/main/yang/elan.yang
vpnservice/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/netvirt/elan/internal/ElanInterfaceManager.java
vpnservice/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/netvirt/elan/internal/ElanOvsdbNodeListener.java
vpnservice/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/netvirt/elan/internal/ElanServiceProvider.java
vpnservice/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/netvirt/elan/utils/ElanUtils.java
vpnservice/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronNetworkChangeListener.java
vpnservice/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronSubnetChangeListener.java
vpnservice/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnServiceAccessor.java [new file with mode: 0644]
vpnservice/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnUtils.java
vpnservice/neutronvpn/neutronvpn-impl/src/main/resources/OSGI-INF/blueprint/blueprint.xml [new file with mode: 0644]

index 69681e39d1206d7dba095de5a9990d1ff3580263..7325efdd610014a5cb6f807f8538b0bbfed80035 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.netvirt.elanmanager.api;
 
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.forwarding.entries.MacEntry;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
 import org.opendaylight.netvirt.elanmanager.exceptions.MacNotFoundException;
 
 import java.util.Collection;
@@ -34,4 +35,8 @@ public interface IElanService {
     List<ElanInstance> getElanInstances();
     List<String> getElanInterfaces(String elanInstanceName);
 
+    void createExternalElanNetwork(ElanInstance elanInstance);
+
+    void createExternalElanNetworks(Node node);
+
 }
index 172f44768d03ba3d4781139f0c00ed6269442f65..6fa6ca567ea7e41a82e4ea10adb4a0cfe572f8e2 100644 (file)
@@ -55,6 +55,10 @@ module elan {
                                 if segment-type is vlan, this ID is a vlan identifier. If segment-type
                                 is vxlan, this ID is a vni";
             }
+            leaf physical-network-name {
+                type string;
+                description "Optional. The name of the phyiscal network attached to the ELAN.";
+            }
             leaf mac-timeout {
                 type uint32 {
                     range "0..65535";
index 0f890ef67d2528eea9e402fe46ec5d06a83e2b65..3192c241a5d2d036347172b3b4c7eed518a9ee14 100644 (file)
@@ -936,8 +936,8 @@ public class ElanInterfaceManager extends AsyncDataTreeChangeListenerBase<ElanIn
 
         elanServiceProvider.getMdsalManager().addFlowToTx(dpId, flowEntity, writeFlowGroupTx);
 
-        // only if vni is present in elanInfo, perform the following
-        if (ElanUtils.isVxlan(elanInfo)) {
+        // only if ELAN can connect to external netowrk, perform the following
+        if (ElanUtils.isVxlan(elanInfo) || ElanUtils.isVlan(elanInfo) || ElanUtils.isFlat(elanInfo)) {
             Flow flowEntity2 = MDSALUtil.buildFlowNew(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, getUnknownDmacFlowRef(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, elanTag, /*SH flag*/true),
                 5, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_UNKNOWN_DMAC.add(BigInteger.valueOf(elanTag)), getMatchesForElanTag(elanTag, /*SH flag*/true),
                 getInstructionsForOutGroup(ElanUtils.getElanLocalBCGID(elanTag)));
index bbecd083cd4fa2efb4c53d4af433feaf7a9c9b4b..1d2cfc965839224566cefd9b1ba97e8de3ec7d5a 100644 (file)
@@ -79,6 +79,7 @@ public class ElanOvsdbNodeListener extends AbstractDataChangeListener<Node> {
     protected void add(InstanceIdentifier<Node> identifier, Node node) {
         logger.debug("ElanOvsdbNodeListener.add, new node detected {}", node);
         doNodeUpdate(node);
+        elanProvider.createExternalElanNetworks(node);
     }
 
     private void doNodeUpdate(Node node) {
index 8861fa6744821659459ff6c3531b0db24d0dedb0..2ade9083a029f3d9ee90dfa5b7a9dc19b377686c 100644 (file)
@@ -30,6 +30,8 @@ import org.opendaylight.netvirt.elan.statusanddiag.ElanStatusMonitor;
 import org.opendaylight.netvirt.elan.utils.ElanClusterUtils;
 import org.opendaylight.netvirt.elan.utils.ElanConstants;
 import org.opendaylight.netvirt.elan.utils.ElanUtils;
+import org.opendaylight.genius.interfacemanager.exceptions.InterfaceAlreadyExistsException;
+import org.opendaylight.genius.interfacemanager.globals.IfmConstants;
 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
 import org.opendaylight.genius.itm.api.IITMProvider;
 import org.opendaylight.genius.mdsalutil.MDSALUtil;
@@ -47,9 +49,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.state.Elan;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.forwarding.entries.MacEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.statistics.rev150824.ElanStatisticsService;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -59,6 +63,7 @@ import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Optional;
 
+
 public class ElanServiceProvider implements BindingAwareProvider, IElanService, AutoCloseable {
 
     private IdManagerService idManager;
@@ -561,4 +566,111 @@ public class ElanServiceProvider implements BindingAwareProvider, IElanService,
     public void setGenerateIntBridgeMac(boolean generateIntBridgeMac) {
         this.generateIntBridgeMac = generateIntBridgeMac;
     }
+
+    @Override
+    public void createExternalElanNetworks(Node node) {
+        if (!bridgeMgr.isIntegrationBridge(node)) {
+            return;
+        }
+
+        List<ElanInstance> elanInstances = getElanInstances();
+        if (elanInstances == null || elanInstances.isEmpty()) {
+            logger.trace("No ELAN instances found");
+            return;
+        }
+
+        for (ElanInstance elanInstance : elanInstances) {
+            String interfaceName = getExtInterfaceName(node, elanInstance.getPhysicalNetworkName());
+            createExternalElanNetwork(elanInstance, node, interfaceName);
+        }
+    }
+
+    @Override
+    public void createExternalElanNetwork(ElanInstance elanInstance) {
+        if (elanInstance.getPhysicalNetworkName() == null) {
+            logger.trace("No physical network attached to {}", elanInstance.getElanInstanceName());
+            return;
+        }
+
+        List<Node> nodes = bridgeMgr.southboundUtils.getOvsdbNodes();
+        if (nodes == null || nodes.isEmpty()) {
+            logger.trace("No OVS nodes found while creating external network for ELAN {}",
+                    elanInstance.getElanInstanceName());
+            return;
+        }
+
+        for (Node node : nodes) {
+            if (bridgeMgr.isIntegrationBridge(node)) {
+                String interfaceName = getExtInterfaceName(node, elanInstance.getPhysicalNetworkName());
+                createExternalElanNetwork(elanInstance, node, interfaceName);
+            }
+        }
+    }
+
+    private void createExternalElanNetwork(ElanInstance elanInstance, Node node, String interfaceName) {
+        if (interfaceName == null) {
+            logger.trace("No physial interface is attached to {} node {}", elanInstance.getPhysicalNetworkName(),
+                    node.getNodeId().getValue());
+        }
+
+        String elanInterfaceName = createIetfInterfaces(elanInstance, interfaceName);
+        addElanInterface(elanInstance.getElanInstanceName(), elanInterfaceName, null, null);
+    }
+
+    /**
+     * Create ietf-interfaces based on the ELAN segment type.<br>
+     * For segment type flat - create transparent interface pointing to the
+     * patch-port attached to the physnet port.<br>
+     * For segment type vlan - create trunk interface pointing to the patch-port
+     * attached to the physnet port + trunk-member interface pointing to the
+     * trunk interface.
+     *
+     * @param elanInstance
+     *            ELAN instance
+     * @param parentRef
+     *            parent interface name
+     * @return the name of the interface to be added to the ELAN instance i.e.
+     *         trunk-member name for vlan network and transparent for flat
+     *         network or null otherwise
+     */
+    private String createIetfInterfaces(ElanInstance elanInstance, String parentRef) {
+        String interfaceName = null;
+
+        try {
+            if (ElanUtils.isFlat(elanInstance)) {
+                interfaceName = parentRef + IfmConstants.OF_URI_PREFIX + "flat";
+                interfaceManager.createVLANInterface(interfaceName, parentRef, null, null, null,
+                        IfL2vlan.L2vlanMode.Transparent);
+            } else if (ElanUtils.isVlan(elanInstance)) {
+                String trunkName = parentRef + IfmConstants.OF_URI_PREFIX + "trunk";
+                interfaceManager.createVLANInterface(interfaceName, parentRef, null, null, null,
+                        IfL2vlan.L2vlanMode.Trunk);
+                Long segmentationId = elanInstance.getSegmentationId();
+                interfaceName = parentRef + IfmConstants.OF_URI_PREFIX + segmentationId;
+                interfaceManager.createVLANInterface(interfaceName, trunkName, null, segmentationId.intValue(), null,
+                        IfL2vlan.L2vlanMode.TrunkMember);
+            }
+        } catch (InterfaceAlreadyExistsException e) {
+            logger.trace("Interface {} was already created", interfaceName);
+        }
+
+        return interfaceName;
+    }
+
+    private String getExtInterfaceName(Node node, String physicalNetworkName) {
+        if (physicalNetworkName == null) {
+            return null;
+        }
+
+        String providerMappingValue = bridgeMgr.getProviderMappingValue(node, physicalNetworkName);
+        if (providerMappingValue == null) {
+            logger.trace("No provider mapping found for physicalNetworkName {} node {}", physicalNetworkName,
+                    node.getNodeId().getValue());
+            return null;
+        }
+
+        return bridgeMgr.southboundUtils.getDataPathId(node) + IfmConstants.OF_URI_SEPARATOR
+                + bridgeMgr.getIntBridgePortNameFor(node, providerMappingValue);
+    }
+
 }
index 1b98d1b1ebf598d8a1dc5eda2e03fd05ffd2664e..58330ebc2c69f42829e5695050eb2349bf2c1d81 100644 (file)
@@ -59,6 +59,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.Elan
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInterfaces;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanState;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanTagNameMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.SegmentTypeFlat;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.SegmentTypeVlan;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.SegmentTypeVxlan;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMac;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMacKey;
@@ -1619,5 +1621,16 @@ public class ElanUtils {
                 && elanInstance.getSegmentType().isAssignableFrom(SegmentTypeVxlan.class)
                 && elanInstance.getSegmentationId() != null && elanInstance.getSegmentationId().longValue() != 0;
     }
+
+    public static boolean isVlan(ElanInstance elanInstance) {
+        return elanInstance != null && elanInstance.getSegmentType() != null
+                && elanInstance.getSegmentType().isAssignableFrom(SegmentTypeVlan.class)
+                && elanInstance.getSegmentationId() != null && elanInstance.getSegmentationId().longValue() != 0;
+    }
+
+    public static boolean isFlat(ElanInstance elanInstance) {
+        return elanInstance != null && elanInstance.getSegmentType() != null
+                && elanInstance.getSegmentType().isAssignableFrom(SegmentTypeFlat.class);
+    }
 }
 
index 73badd6a7310d26019b7022ffd4efe98305afa5d..ac0d853df726e64b6139953ee55c5050c54fe621 100644 (file)
@@ -16,15 +16,15 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.genius.mdsalutil.AbstractDataChangeListener;
 import org.opendaylight.genius.mdsalutil.MDSALUtil;
 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronUtils;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.Networks;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.SegmentTypeBase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.ext.rev150712.NetworkL3Extension;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.Networks;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
@@ -86,10 +86,11 @@ public class NeutronNetworkChangeListener extends AbstractDataChangeListener<Net
             LOG.error("Neutronvpn doesn't support gre network provider type for this network {}.", input);
             return;
         }
-        //Create ELAN instance for this network
-        createElanInstance(input);
-        if ( input.getAugmentation(NetworkL3Extension.class) != null &&
-                input.getAugmentation(NetworkL3Extension.class).isExternal()) {
+        // Create ELAN instance for this network
+        ElanInstance elanInstance = createElanInstance(input);
+        // Create ELAN interface and IETF interfaces for the physical network
+        NeutronvpnServiceAccessor.getElanProvider().createExternalElanNetwork(elanInstance);
+        if (input.getAugmentation(NetworkL3Extension.class).isExternal()) {
             nvpnNatManager.addExternalNetwork(input);
             NeutronvpnUtils.addToNetworkCache(input);
         }
@@ -106,11 +107,14 @@ public class NeutronNetworkChangeListener extends AbstractDataChangeListener<Net
             return;
         }
         //Delete ELAN instance for this network
-        deleteElanInstance(input.getUuid().getValue());
+        String elanInstanceName = input.getUuid().getValue();
+        deleteElanInstance(elanInstanceName);
         if (input.getAugmentation(NetworkL3Extension.class).isExternal()) {
             nvpnNatManager.removeExternalNetwork(input);
             NeutronvpnUtils.removeFromNetworkCache(input);
         }
+
+        // TODO: delete elan-interfaces for physnet port
     }
 
     @Override
@@ -121,22 +125,27 @@ public class NeutronNetworkChangeListener extends AbstractDataChangeListener<Net
         }
     }
 
-    private void createElanInstance(Network input) {
+    private ElanInstance createElanInstance(Network input) {
         String elanInstanceName = input.getUuid().getValue();
         Class<? extends SegmentTypeBase> segmentType = NeutronvpnUtils.getSegmentTypeFromNeutronNetwork(input);
         String segmentationId = NeutronUtils.getSegmentationIdFromNeutronNetwork(input);
+        String physicalNetworkName = NeutronvpnUtils.getPhysicalNetworkName(input);
         ElanInstanceBuilder elanInstanceBuilder = new ElanInstanceBuilder().setElanInstanceName(elanInstanceName);
         if (segmentType != null) {
             elanInstanceBuilder.setSegmentType(segmentType);
             if (segmentationId != null) {
                 elanInstanceBuilder.setSegmentationId(Long.valueOf(segmentationId));
             }
+            if (physicalNetworkName != null) {
+                elanInstanceBuilder.setPhysicalNetworkName(physicalNetworkName);
+            }
         }
         elanInstanceBuilder.setKey(new ElanInstanceKey(elanInstanceName));
         ElanInstance elanInstance = elanInstanceBuilder.build();
         InstanceIdentifier<ElanInstance> id = InstanceIdentifier.builder(ElanInstances.class)
                 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
         MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, id, elanInstance);
+        return elanInstance;
     }
 
     private void deleteElanInstance(String elanInstanceName) {
index b033b7648e5249ae33b190eb79df3fb21a7f7bf2..3910967568489410a63b15ba2514d8f00feca3a1 100644 (file)
@@ -98,8 +98,8 @@ public class NeutronSubnetChangeListener extends AbstractDataChangeListener<Subn
         Uuid networkId = input.getNetworkId();
         Network network = NeutronvpnUtils.getNeutronNetwork(broker, networkId);
         if (network == null || !NeutronvpnUtils.isNetworkTypeSupported(network)) {
-            //FIXME: This should be removed when support for VLAN and GRE network types is added
-            LOG.error("neutron vpn doesn't support vlan/gre network provider type for the port {} which is part of network {}."
+            //FIXME: This should be removed when support for GRE network types is added
+            LOG.error("neutron vpn doesn't support gre network provider type for the port {} which is part of network {}."
                     + " Skipping the processing of Subnet remove DCN", input.getName(), network);
             return;
         }
diff --git a/vpnservice/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnServiceAccessor.java b/vpnservice/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnServiceAccessor.java
new file mode 100644 (file)
index 0000000..968ae5a
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2016 Hewlett Packard Enterprise, Co. 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;
+
+import org.opendaylight.netvirt.elanmanager.api.IElanService;
+
+/**
+ * FIXME :This is a temp hack to access OSGi services from blueprint.
+ * Can be removed after neutronvpn migration to blueprint is complete https://git.opendaylight.org/gerrit/#/c/39001/
+ *
+ */
+public class NeutronvpnServiceAccessor {
+    private static IElanService elanProvider;
+
+    public NeutronvpnServiceAccessor(IElanService elanProvider) {
+        NeutronvpnServiceAccessor.elanProvider = elanProvider;
+    }
+
+    public static IElanService getElanProvider() {
+        return elanProvider;
+    }
+
+}
index 1f58099241dc2a0ce8a35de428d2e0f601109383..3a019c47bd7e28c21d61c19768717e2207f8cbc2 100644 (file)
@@ -66,7 +66,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.por
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.PortKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.portsecurity.rev150712.PortSecurityExtension;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.provider.ext.rev150712.NetworkProviderExtension;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.provider.ext.rev150712.neutron.networks.network.Segments;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
@@ -834,6 +833,10 @@ public class NeutronvpnUtils {
         return providerExtension != null ? NETWORK_MAP.get(providerExtension.getNetworkType()) : null;
     }
 
+    public static String getPhysicalNetworkName(Network network) {
+        NetworkProviderExtension providerExtension = network.getAugmentation(NetworkProviderExtension.class);
+        return providerExtension != null ? providerExtension.getPhysicalNetwork() : null;
+    }
     static InstanceIdentifier<VpnPortipToPort> buildVpnPortipToPortIdentifier(String vpnName, String fixedIp) {
         InstanceIdentifier<VpnPortipToPort> id = InstanceIdentifier.builder(NeutronVpnPortipPortData.class).child
                 (VpnPortipToPort.class, new VpnPortipToPortKey(fixedIp, vpnName)).build();
diff --git a/vpnservice/neutronvpn/neutronvpn-impl/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/vpnservice/neutronvpn/neutronvpn-impl/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644 (file)
index 0000000..b13cbbe
--- /dev/null
@@ -0,0 +1,6 @@
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+    <reference id="elanProvider" interface="org.opendaylight.netvirt.elanmanager.api.IElanService" availability="optional" />
+    <bean id="neutronvpnServiceAccessor" class="org.opendaylight.netvirt.neutronvpn.NeutronvpnServiceAccessor">
+        <argument ref="elanProvider" />
+    </bean>
+</blueprint>
\ No newline at end of file