First pass changes for Netvirt classifier rule installation. Writing to INGRES_ACL... 52/28352/2
authorArun Yerra <arunsarat@yahoo.com>
Tue, 13 Oct 2015 11:31:17 +0000 (04:31 -0700)
committerSam Hague <shague@redhat.com>
Sat, 17 Oct 2015 02:12:30 +0000 (22:12 -0400)
Conflicts:
openstack/net-virt-sfc/features/production/src/main/features/features.xml
openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/NetvirtSfcProvider.java

Change-Id: Ie1f76ceb301aed90acad49dceacbd8bbfac2dd49
Signed-off-by: Arun S Yerra <arunsarat@yahoo.com>
Signed-off-by: Sam Hague <shague@redhat.com>
openstack/net-virt-providers/pom.xml
openstack/net-virt-sfc/api/pom.xml
openstack/net-virt-sfc/features/production/pom.xml
openstack/net-virt-sfc/features/production/src/main/features/features.xml
openstack/net-virt-sfc/impl/pom.xml
openstack/net-virt-sfc/impl/src/main/config/default-config.xml
openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/openflow13/NetvirtSfcOF13Provider.java
openstack/net-virt-sfc/impl/src/test/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/netvirt/sfc/rev141210/NetvirtSfcModuleTest.java
openstack/net-virt-sfc/it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/NetvirtSfcIT.java
openstack/net-virt-sfc/karaf/pom.xml

index 780944ff5af5b5db1fb5c38ac6e829570e1b8321..76ca876bdd34368c4b7c57b54e54730bf4038838 100644 (file)
@@ -258,6 +258,9 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
           <instructions>
             <Embed-Dependency>utils.config,utils.mdsal-openflow;type=!pom;inline=false</Embed-Dependency>
             <Embed-Transitive>true</Embed-Transitive>
+            <Export-Package>
+              org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.*
+            </Export-Package>
           </instructions>
         </configuration>
       </plugin>
index 706531d6df2f8c7c9eeb07090eab1314b7f21a20..8b4e1874ad956373aa21efa1338cab398d51685b 100644 (file)
@@ -36,4 +36,22 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <artifactId>yang-ext</artifactId>
     </dependency>
   </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Export-Package>
+              org.opendaylight.yang.gen.v1.*;
+            </Export-Package>
+            <!--<Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>-->
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
 </project>
index 6953792d3699af3fb6c4423931cd96fb6d813fe4..01fb239e0a0b09ca4db7f278c487135641b09322 100644 (file)
@@ -24,12 +24,14 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
     <maven>3.1.1</maven>
   </prerequisites>
   <properties>
+    <configfile.directory>etc/opendaylight/karaf</configfile.directory>
+    <dlux.version>0.3.0-SNAPSHOT</dlux.version>
     <mdsal.model.version>0.8.0-SNAPSHOT</mdsal.model.version>
     <mdsal.version>1.3.0-SNAPSHOT</mdsal.version>
+    <openflowplugin.version>0.2.0-SNAPSHOT</openflowplugin.version>
     <restconf.version>1.3.0-SNAPSHOT</restconf.version>
+    <sfc.version>0.2.0-SNAPSHOT</sfc.version>
     <yangtools.version>0.8.0-SNAPSHOT</yangtools.version>
-    <dlux.version>0.3.0-SNAPSHOT</dlux.version>
-    <configfile.directory>etc/opendaylight/karaf</configfile.directory>
   </properties>
   <dependencyManagement>
     <dependencies>
@@ -48,6 +50,13 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
         <type>pom</type>
         <scope>import</scope>
       </dependency>
+      <dependency>
+        <groupId>org.opendaylight.ovsdb</groupId>
+        <artifactId>ovsdb-artifacts</artifactId>
+        <version>${project.version}</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
     </dependencies>
   </dependencyManagement>
   <dependencies>
@@ -91,6 +100,37 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
       <type>xml</type>
       <scope>runtime</scope>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.ovsdb</groupId>
+      <artifactId>features-ovsdb</artifactId>
+      <classifier>features</classifier>
+      <version>${project.version}</version>
+      <type>xml</type>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.openflowplugin</groupId>
+      <artifactId>features-openflowplugin</artifactId>
+      <version>${openflowplugin.version}</version>
+      <classifier>features</classifier>
+      <type>xml</type>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.sfc</groupId>
+      <artifactId>features-sfc</artifactId>
+      <version>${sfc.version}</version>
+      <classifier>features</classifier>
+      <type>xml</type>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.sfc</groupId>
+      <artifactId>features-sfc-ovs</artifactId>
+      <version>${sfc.version}</version>
+      <classifier>features</classifier>
+      <type>xml</type>
+      <scope>runtime</scope>
+    </dependency>
     <dependency>
       <groupId>${project.groupId}</groupId>
       <artifactId>openstack.net-virt-sfc-impl</artifactId>
@@ -120,5 +160,10 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
       <artifactId>utils.mdsal-utils</artifactId>
       <version>${project.version}</version>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.ovsdb</groupId>
+      <artifactId>utils.servicehelper</artifactId>
+      <version>${project.version}</version>
+    </dependency>
   </dependencies>
 </project>
index 3413bc8d18a02b4a45d38d13aaf1d3b4689ed6b9..1b4ca16239b492ef20782f1e8df8308edc3bf561 100644 (file)
@@ -10,21 +10,31 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
 <features name="odl-ovsdb-sfc-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
-  <repository>mvn:org.opendaylight.yangtools/features-yangtools/${yangtools.version}/xml/features</repository>
   <repository>mvn:org.opendaylight.controller/features-mdsal/${mdsal.version}/xml/features</repository>
+  <repository>mvn:org.opendaylight.dlux/features-dlux/${dlux.version}/xml/features</repository>
   <repository>mvn:org.opendaylight.mdsal.model/features-mdsal-model/${mdsal.model.version}/xml/features</repository>
   <repository>mvn:org.opendaylight.netconf/features-restconf/${restconf.version}/xml/features</repository>
-  <repository>mvn:org.opendaylight.dlux/features-dlux/${dlux.version}/xml/features</repository>
-  <repository>mvn:org.opendaylight.ovsdb/southbound-features/1.2.1-SNAPSHOT/xml/features</repository>
+  <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin/${openflowplugin.version}/xml/features</repository>
+  <repository>mvn:org.opendaylight.ovsdb/features-ovsdb/${project.version}/xml/features</repository>
+  <repository>mvn:org.opendaylight.ovsdb/southbound-features/${project.version}/xml/features</repository>
+  <repository>mvn:org.opendaylight.sfc/features-sfc/${sfc.version}/xml/features</repository>
+  <repository>mvn:org.opendaylight.sfc/features-sfc-ovs/${sfc.version}/xml/features</repository>
+  <repository>mvn:org.opendaylight.yangtools/features-yangtools/${yangtools.version}/xml/features</repository>
   <feature name='odl-ovsdb-sfc-api' version='${project.version}' description='OpenDaylight :: ovsdb-sfc :: api'>
     <feature version='${mdsal.model.version}'>odl-mdsal-models</feature>
     <bundle>mvn:org.opendaylight.ovsdb/openstack.net-virt-sfc-api/${project.version}</bundle>
   </feature>
   <feature name='odl-ovsdb-sfc' version='${project.version}' description='OpenDaylight :: ovsdb-sfc'>
     <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
+    <feature version="${openflowplugin.version}">odl-openflowplugin-nsf-model</feature>
     <feature version='${project.version}'>odl-ovsdb-southbound-impl</feature>
-    <bundle>mvn:org.opendaylight.ovsdb/utils.mdsal-utils/${project.version}</bundle>
+    <feature version='${project.version}'>odl-ovsdb-openstack</feature>
+    <feature version='${sfc.version}'>odl-sfc-core</feature>
+    <feature version='${sfc.version}'>odl-sfc-ovs</feature>
+    <feature version="${openflowplugin.version}">odl-openflowplugin-flow-services</feature>
     <feature version='${project.version}'>odl-ovsdb-sfc-api</feature>
+    <bundle>mvn:org.opendaylight.ovsdb/utils.mdsal-utils/${project.version}</bundle>
+    <bundle>mvn:org.opendaylight.ovsdb/utils.servicehelper/${project.version}</bundle>
     <bundle>mvn:org.opendaylight.ovsdb/openstack.net-virt-sfc-impl/${project.version}</bundle>
     <configfile finalname="${configfile.directory}/openstack.net-virt-sfc.xml">mvn:org.opendaylight.ovsdb/openstack.net-virt-sfc-impl/${project.version}/xml/config</configfile>
   </feature>
index 9de4d9c88a85950c1a0fbcab7f20ec1eaec72295..7795793b612ea2b6079ced16c06f8581327b7683 100644 (file)
@@ -25,7 +25,10 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <packaging>bundle</packaging>
 
   <properties>
+    <networkconfig.neutron.version>0.6.0-SNAPSHOT</networkconfig.neutron.version>
+    <openflowplugin.version>0.2.0-SNAPSHOT</openflowplugin.version>
     <sonar.jacoco.itReportPath>../it/target/jacoco-it.exec</sonar.jacoco.itReportPath>
+    <sfc.project.version>0.2.0-SNAPSHOT</sfc.project.version>
   </properties>
 
   <dependencies>
@@ -34,6 +37,31 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <artifactId>openstack.net-virt-sfc-api</artifactId>
       <version>${project.version}</version>
     </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>openstack.net-virt</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>openstack.net-virt-providers</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>utils.mdsal-utils</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>utils.mdsal-openflow</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.ovsdb</groupId>
+      <artifactId>utils.servicehelper</artifactId>
+      <version>${project.version}</version>
+    </dependency>
     <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>
@@ -59,9 +87,33 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <artifactId>sal-common-api</artifactId>
     </dependency>
     <dependency>
-      <groupId>org.opendaylight.ovsdb</groupId>
-      <artifactId>utils.mdsal-utils</artifactId>
-      <version>${project.version}</version>
+      <groupId>org.opendaylight.openflowplugin.model</groupId>
+      <artifactId>model-flow-base</artifactId>
+      <version>${openflowplugin.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.openflowplugin.model</groupId>
+      <artifactId>model-flow-service</artifactId>
+      <version>${openflowplugin.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.mdsal.model</groupId>
+      <artifactId>ietf-topology</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.sfc</groupId>
+      <artifactId>sfc-model</artifactId>
+      <version>${sfc.project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.sfc</groupId>
+      <artifactId>sfc-ovs</artifactId>
+      <version>${sfc.project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.sfc</groupId>
+      <artifactId>sfc-provider</artifactId>
+      <version>${sfc.project.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.yangtools</groupId>
@@ -92,6 +144,17 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
 
   <build>
     <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Embed-Dependency>utils.mdsal-openflow;type=!pom;inline=false</Embed-Dependency>
+            <Embed-Transitive>true</Embed-Transitive>
+          </instructions>
+        </configuration>
+      </plugin>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-checkstyle-plugin</artifactId>
index 402b72d8828a19334051ebbe07f668fdbcc416ee..1aa106ae18a911d76b08b871f2e182aa6f9ba65a 100644 (file)
@@ -10,6 +10,9 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <required-capabilities>
     <capability>urn:opendaylight:params:xml:ns:yang:netvirt:sfc?module=netvirt-sfc&amp;revision=2014-12-10</capability>
     <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&amp;revision=2013-10-28</capability>
+    <capability>urn:opendaylight:params:xml:ns:yang:southbound:impl?module=southbound-impl&amp;revision=2014-12-10</capability>
+    <capability>urn:opendaylight:params:xml:ns:yang:netvirt:impl?module=netvirt-impl&amp;revision=2015-05-13</capability>
+    <capability>urn:opendaylight:params:xml:ns:yang:netvirt:providers:impl?module=netvirt-providers-impl&amp;revision=2015-05-13</capability>
   </required-capabilities>
   <configuration>
 
index ca75a5879cf681a5967d9ab3a8fee0f5f7683f5c..1621e722c32d54f1135bbf590f798633e83ecb3f 100644 (file)
 
 package org.opendaylight.ovsdb.openstack.netvirt.sfc.openflow13;
 
+import java.util.Iterator;
+import java.util.List;
+
 import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
+import org.opendaylight.ovsdb.openstack.netvirt.api.NodeCacheManager;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.PipelineOrchestrator;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
+import org.opendaylight.ovsdb.utils.mdsal.openflow.InstructionUtils;
+import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
+import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
+import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
+import org.opendaylight.sfc.provider.api.SfcProviderServiceForwarderAPI;
+import org.opendaylight.sfc.sfc_ovs.provider.SfcOvsUtil;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.AccessList;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.AccessListEntry;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.access.list.entry.Actions;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.access.list.entry.Matches;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.access.list.entry.actions.packet.handling.Deny;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.access.list.entry.actions.packet.handling.Permit;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.access.list.entry.matches.ace.type.AceEth;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.access.list.entry.matches.ace.type.AceIp;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.access.list.entry.matches.ace.type.ace.ip.ace.ip.version.AceIpv4;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.sffs.Sff;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Open vSwitch OpenFlow 1.3 Networking Provider for Netvirt SFC
  * @author Arun Yerra
  */
 public class NetvirtSfcOF13Provider implements INetvirtSfcOF13Provider{
+    private static final Logger LOG = LoggerFactory.getLogger(NetvirtSfcOF13Provider.class);
+    private static final int DEFAULT_FLOW_PRIORITY = 32768;
+    private volatile NodeCacheManager nodeCacheManager;
+    private volatile Southbound southbound;
+    private MdsalUtils dbutils;
+    private PipelineOrchestrator orchestrator;
 
-    private final DataBroker dataService;
-
+    /**
+     * {@link NetvirtSfcOF13Provider} constructor.
+     * @param dataBroker MdSal {@link DataBroker}
+     */
     public NetvirtSfcOF13Provider(final DataBroker dataBroker) {
-        this.dataService = Preconditions.checkNotNull(dataBroker, "DataBroker can not be null!");
+        Preconditions.checkNotNull(dataBroker, "Input dataBroker cannot be NULL!");
+
+        //this.dataService = dataBroker;
+        dbutils = new MdsalUtils(dataBroker);
+
+        this.setDependencies(null);
     }
 
     @Override
     public void addClassifierRules(Sff sff, AccessList acl) {
-        // TODO Auto-generated method stub
+        Preconditions.checkNotNull(sff, "Input service function forwarder cannot be NULL!");
+        Preconditions.checkNotNull(acl, "Input accesslist cannot be NULL!");
+
+        // Validate if any service function forwarder exists by the name, using SFC provider APIs.
+        ServiceFunctionForwarder serviceForwarder =
+                SfcProviderServiceForwarderAPI.readServiceFunctionForwarder(sff.getName());
+        if (serviceForwarder == null) {
+            LOG.debug("Service Function Forwarder = {} not yet configured. Skip processing !!", sff.getName());
+            return;
+        }
+
+        // If a service function forwarder exists, then get the corresponding OVS Bridge details and Openflow NodeId.
+        // If OVS Bridge augmentation is configured, the following API returns NULL.
+        String datapathId = SfcOvsUtil.getOpenFlowNodeIdForSff(serviceForwarder);
+        if (datapathId == null) {
+            LOG.debug("Service Function Forwarder = {} is not augemented with "
+                    + "OVS Bridge Information. Skip processing!!", sff.getName());
+        }
+        // If openflow Node Id is NULL, get all the bridge nodes using southbound apis and fetch
+        // SFF with matching name. From this bridge name, get the openflow data path ID.
+        if (datapathId == null) {
+            Node node = null;
+            final List<Node> nodes = nodeCacheManager.getBridgeNodes();
+            if (nodes.isEmpty()) {
+                LOG.debug("Noop with Classifier Creation on SFF={}. No Bridges configured YET!!", sff.getName());
+            } else {
+                for (Node dstNode : nodes) {
+                    LOG.debug("Processing Node={}, sff={}", dstNode.getNodeId().getValue(), sff.getName());
+                    if (dstNode.getNodeId().getValue().equalsIgnoreCase(sff.getName())) {
+                        LOG.debug("Found matching OVSDB Bridge Name!!= {}", dstNode.getNodeId().getValue());
+                        node = dstNode;
+                        break;
+                    }
+                }
+            }
+        }
+
+        LOG.debug("Processing the Classifier rules on Node={}", datapathId);
+        if (datapathId != null) {
+            // Program the OF flow on the corresponding open flow node.
+            Iterator<AccessListEntry> itr = acl.getAccessListEntries().getAccessListEntry().iterator();
+            while (itr.hasNext()) {
+                AccessListEntry entry = itr.next();
+                programOFRules(entry, datapathId, true);
+            }
+        }
+    }
+
+    private void programOFRules(AccessListEntry entry, String datapathId, boolean write) {
+        NodeBuilder nodeBuilder = new NodeBuilder();
+        nodeBuilder.setId(new NodeId(Constants.OPENFLOW_NODE_PREFIX + datapathId));
+        nodeBuilder.setKey(new NodeKey(nodeBuilder.getId()));
+
+        //Create the match using match builder, by parsing the Accesslist Entry Match.
+        MatchBuilder matchBuilder = null;
+        matchBuilder = buildMatch(entry.getRuleName(), entry.getMatches(), datapathId);
+
+        InstructionsBuilder isb = null;
+        isb = buildActions(entry.getRuleName(), entry.getActions(), datapathId);
+
+        String flowId = "NETVIRT_SFC_FLOW" + "_" + entry.getRuleName();
+
+        FlowBuilder flowBuilder = new FlowBuilder();
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setMatch(matchBuilder.build());
+        flowBuilder.setPriority(DEFAULT_FLOW_PRIORITY);
+        flowBuilder.setBarrier(true);
+        flowBuilder.setTableId(this.getTable());
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+
+        flowBuilder.setInstructions(isb.build());
+
+        if (write) {
+            writeFlow(flowBuilder, nodeBuilder);
+        } else {
+            removeFlow(flowBuilder, nodeBuilder);
+        }
+    }
+
+    private InstructionsBuilder buildActions(String ruleName, Actions actions, String datapathId) {
+        InstructionBuilder ib = new InstructionBuilder();
+
+        if (actions.getPacketHandling() instanceof Deny) {
+            InstructionUtils.createDropInstructions(ib);
+        } else if (actions.getPacketHandling() instanceof Permit) {
+            //Permit actPermit = (Permit) actions.getPacketHandling();
+        } else {
+            InstructionUtils.createDropInstructions(ib);
+        }
+
+        ib.setOrder(0);
+        ib.setKey(new InstructionKey(0));
+        // Instructions List Stores Individual Instructions
+        List<Instruction> instructions = Lists.newArrayList();
+        instructions.add(ib.build());
+
+        // Call the InstructionBuilder Methods Containing Actions
+        ib = this.getMutablePipelineInstructionBuilder();
+        ib.setOrder(1);
+        ib.setKey(new InstructionKey(1));
+        instructions.add(ib.build());
 
+        // Add InstructionBuilder to the Instruction(s)Builder List
+        InstructionsBuilder isb = new InstructionsBuilder();
+        isb.setInstruction(instructions);
+        return isb;
+    }
+
+    private MatchBuilder buildMatch(String ruleName, Matches matches, String dpId) {
+        MatchBuilder matchBuilder = new MatchBuilder();
+
+        if (matches.getAceType() instanceof AceIp) {
+            AceIp aceIp = (AceIp)matches.getAceType();
+            if (aceIp.getAceIpVersion() instanceof AceIpv4) {
+                AceIpv4 aceIpv4 = (AceIpv4) aceIp.getAceIpVersion();
+                MatchUtils.createSrcL3IPv4Match(matchBuilder, aceIpv4.getSourceIpv4Address());
+                MatchUtils.createDstL3IPv4Match(matchBuilder, aceIpv4.getDestinationIpv4Address());
+                MatchUtils.createIpProtocolMatch(matchBuilder, aceIp.getIpProtocol());
+                MatchUtils.addLayer4Match(matchBuilder, aceIp.getIpProtocol().intValue(),
+                        aceIp.getSourcePortRange().getLowerPort().getValue().intValue(),
+                        aceIp.getDestinationPortRange().getLowerPort().getValue().intValue());
+            }
+        } else if (matches.getAceType() instanceof AceEth) {
+            AceEth aceEth = (AceEth) matches.getAceType();
+            MatchUtils.createEthSrcMatch(matchBuilder, new MacAddress(aceEth.getSourceMacAddress().getValue()));
+            MatchUtils.createDestEthMatch(matchBuilder, new MacAddress(aceEth.getDestinationMacAddress().getValue()),
+                    new MacAddress(aceEth.getDestinationMacAddressMask().getValue()));
+        }
+
+        //MatchUtils.createInPortMatch(matchBuilder, Long.getLong(dpId), Long.getLong(matches.getInputInterface()));
+        return matchBuilder;
     }
 
     @Override
@@ -36,4 +230,59 @@ public class NetvirtSfcOF13Provider implements INetvirtSfcOF13Provider{
         // TODO Auto-generated method stub
 
     }
+
+
+    protected void writeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
+        LOG.debug("writeFlow: flowBuilder: {}, nodeBuilder: {}",
+                flowBuilder.build(), nodeBuilder.build());
+        dbutils.merge(LogicalDatastoreType.CONFIGURATION, createNodePath(nodeBuilder), nodeBuilder.build());
+        dbutils.put(LogicalDatastoreType.CONFIGURATION, createFlowPath(flowBuilder, nodeBuilder), flowBuilder.build());
+    }
+
+    protected void removeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
+        dbutils.delete(LogicalDatastoreType.CONFIGURATION, createFlowPath(flowBuilder, nodeBuilder));
+    }
+
+    private String getDpid(Node node) {
+        long dpid = southbound.getDataPathId(node);
+        if (dpid == 0) {
+            LOG.warn("getDpid: DPID could not be found for node: {}", node.getNodeId().getValue());
+        }
+        return String.valueOf(dpid);
+    }
+
+    private static InstanceIdentifier<Flow> createFlowPath(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
+        return InstanceIdentifier.builder(Nodes.class)
+                .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class,
+                        nodeBuilder.getKey())
+                .augmentation(FlowCapableNode.class)
+                .child(Table.class, new TableKey(flowBuilder.getTableId()))
+                .child(Flow.class, flowBuilder.getKey()).build();
+    }
+
+    private static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node>
+        createNodePath(NodeBuilder nodeBuilder) {
+        return InstanceIdentifier.builder(Nodes.class)
+                .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class,
+                        nodeBuilder.getKey()).build();
+    }
+
+    private short getTable() {
+        return Service.INGRESS_ACL.getTable();
+    }
+
+    private final InstructionBuilder getMutablePipelineInstructionBuilder() {
+        Service nextService = orchestrator.getNextServiceInPipeline(Service.INGRESS_ACL);
+        if (nextService != null) {
+            return InstructionUtils.createGotoTableInstructions(new InstructionBuilder(), nextService.getTable());
+        } else {
+            return InstructionUtils.createDropInstructions(new InstructionBuilder());
+        }
+    }
+
+    private void setDependencies(ServiceReference serviceReference) {
+        nodeCacheManager = (NodeCacheManager) ServiceHelper.getGlobalInstance(NodeCacheManager.class, this);
+        southbound = (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
+        orchestrator = (PipelineOrchestrator) ServiceHelper.getGlobalInstance(PipelineOrchestrator.class, this);
+    }
 }
index 6bb1e19d294703a665dd6a95d66f8ed55e3b97cb..c5b03f0ed7eb72ee5f9d1a6f86e3639221b98531 100644 (file)
@@ -14,6 +14,7 @@ import org.opendaylight.controller.config.api.ModuleIdentifier;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.ovsdb.openstack.netvirt.sfc.NetvirtSfcProvider;
+import org.osgi.framework.BundleContext;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
 
 import javax.management.ObjectName;
@@ -45,7 +46,6 @@ public class NetvirtSfcModuleTest {
 
         // create instance of module with injected mocks
         NetvirtSfcModule module = new NetvirtSfcModule(mock(ModuleIdentifier.class), dependencyResolver);
-        //module.setDataBroker(mock(ObjectName.class));
         // getInstance calls resolveInstance to get the broker dependency and then calls createInstance
         AutoCloseable closeable = module.getInstance();
         ((NetvirtSfcProvider)closeable).onSessionInitiated(session);
index 5fbe1ca5c186069949be405f3f71be9fd33cc646..ee023bef086a783510b9e551f4049e9d591bc011 100644 (file)
@@ -8,6 +8,8 @@
 
 package org.opendaylight.ovsdb.openstack.netvirt.sfc;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
@@ -30,6 +32,7 @@ import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.mdsal.it.base.AbstractMdsalTestBase;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
 import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.AclUtils;
 import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.ClassifierUtils;
 import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.SfcUtils;
@@ -55,6 +58,10 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
 import org.opendaylight.yangtools.concepts.Builder;
 import org.opendaylight.yangtools.yang.binding.DataObject;
@@ -63,6 +70,7 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.ops4j.pax.exam.Configuration;
 import org.ops4j.pax.exam.Option;
 import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.karaf.options.LogLevelOption;
 import org.ops4j.pax.exam.karaf.options.LogLevelOption.LogLevel;
 import org.ops4j.pax.exam.options.MavenUrlReference;
 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
@@ -89,7 +97,8 @@ public class NetvirtSfcIT extends AbstractMdsalTestBase {
     public static final String CONNECTION_TYPE_ACTIVE = "active";
     public static final String CONNECTION_TYPE_PASSIVE = "passive";
     public static final String DEFAULT_SERVER_PORT = "6640";
-    public static final String BRIDGE_NAME = "brtest";
+    public static final String INTEGRATION_BRIDGE_NAME = "br-int";
+    private static final String NETVIRT_TOPOLOGY_ID = "netvirt:1";
 
     @Override
     public String getModuleName() {
@@ -145,11 +154,17 @@ public class NetvirtSfcIT extends AbstractMdsalTestBase {
 
     @Override
     public Option getLoggingOption() {
-        Option option = editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
-                logConfiguration(NetvirtSfcIT.class),
-                LogLevel.INFO.name());
-        option = composite(option, super.getLoggingOption());
-        return option;
+        return composite(
+                editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
+                        logConfiguration(NetvirtSfcIT.class),
+                        LogLevel.INFO.name()),
+                editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
+                        "log4j.logger.org.opendaylight.ovsdb.openstack.netvirt.sfc",
+                        LogLevel.INFO.name()),
+                /*editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
+                        "log4j.logger.org.opendaylight.ovsdb",
+                        LogLevelOption.LogLevel.TRACE.name()),*/
+                super.getLoggingOption());
     }
 
     protected String usage() {
@@ -187,11 +202,13 @@ public class NetvirtSfcIT extends AbstractMdsalTestBase {
             e.printStackTrace();
         }
 
+        getProperties();
+
         DataBroker dataBroker = getDatabroker(getProviderContext());
         mdsalUtils = new MdsalUtils(dataBroker);
         assertNotNull("mdsalUtils should not be null", mdsalUtils);
         southboundUtils = new SouthboundUtils(mdsalUtils);
-        getProperties();
+        assertTrue("Did not find " + NETVIRT_TOPOLOGY_ID, getNetvirtTopology());
         setup.set(true);
     }
 
@@ -225,6 +242,30 @@ public class NetvirtSfcIT extends AbstractMdsalTestBase {
         return dataBroker;
     }
 
+    private Boolean getNetvirtTopology() {
+        LOG.info("getNetvirtTopology: looking for {}...", NETVIRT_TOPOLOGY_ID);
+        Boolean found = false;
+        final TopologyId topologyId = new TopologyId(new Uri(NETVIRT_TOPOLOGY_ID));
+        InstanceIdentifier<Topology> path =
+                InstanceIdentifier.create(NetworkTopology.class).child(Topology.class, new TopologyKey(topologyId));
+        for (int i = 0; i < 60; i++) {
+            Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, path);
+            if (topology != null) {
+                LOG.info("getNetvirtTopology: found {}...", NETVIRT_TOPOLOGY_ID);
+                found = true;
+                break;
+            } else {
+                LOG.info("getNetvirtTopology: still looking ({})...", i);
+                try {
+                    Thread.sleep(1000);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return found;
+    }
+
     @Test
     public void testNetvirtSfcFeatureLoad() {
         assertTrue(true);
@@ -287,35 +328,41 @@ public class NetvirtSfcIT extends AbstractMdsalTestBase {
         assertNull(clazz.getSimpleName() + " should be null", result);
     }
 
+    /*
+     * Connect to an ovsdb node. Netvirt should add br-int, add the controller address
+     * and program the pipeline flows.
+     */
     @Test
     public void testDoIt() throws InterruptedException {
         ConnectionInfo connectionInfo = southboundUtils.getConnectionInfo(addressStr, portStr);
-        Node ovsdbNode = southboundUtils.connectOvsdbNode(connectionInfo);
-
-        String controllerTarget = SouthboundUtil.getControllerTarget(ovsdbNode);
-        assertNotNull("Failed to get controller target", controllerTarget);
-        List<ControllerEntry> setControllerEntry = southboundUtils.createControllerEntry(controllerTarget);
-        Uri setUri = new Uri(controllerTarget);
-        Assert.assertTrue(southboundUtils.addBridge(connectionInfo, null, BRIDGE_NAME, null, true,
-                SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null,
-                setControllerEntry, null));
-        OvsdbBridgeAugmentation bridge = southboundUtils.getBridge(connectionInfo, BRIDGE_NAME);
-        Assert.assertNotNull("bridge was not found: " + BRIDGE_NAME,  bridge);
-        Assert.assertNotNull("ControllerEntry was not found: " + setControllerEntry.iterator().next(),
-                bridge.getControllerEntry());
-        List<ControllerEntry> getControllerEntries = bridge.getControllerEntry();
-        for (ControllerEntry entry : getControllerEntries) {
-            if (entry.getTarget() != null) {
-                Assert.assertEquals(setUri.toString(), entry.getTarget().toString());
+        assertNotNull("connection failed", southboundUtils.connectOvsdbNode(connectionInfo));
+        assertNotNull("node is not connected", southboundUtils.getOvsdbNode(connectionInfo));
+        ControllerEntry controllerEntry;
+        // Loop 10s checking if the controller was added
+        for (int i = 0; i < 10; i++) {
+            Node ovsdbNode = southboundUtils.getOvsdbNode(connectionInfo);
+            assertNotNull("ovsdb node not found", ovsdbNode);
+            String controllerTarget = SouthboundUtil.getControllerTarget(ovsdbNode);
+            assertNotNull("Failed to get controller target", controllerTarget);
+            OvsdbBridgeAugmentation bridge = southboundUtils.getBridge(connectionInfo, INTEGRATION_BRIDGE_NAME);
+            assertNotNull(bridge);
+            assertNotNull(bridge.getControllerEntry());
+            controllerEntry = bridge.getControllerEntry().iterator().next();
+            assertEquals(controllerTarget, controllerEntry.getTarget().getValue());
+            if (controllerEntry.isIsConnected()) {
+                Assert.assertTrue(controllerEntry.isIsConnected());
+                break;
             }
+            Thread.sleep(1000);
         }
 
         /* TODO: add code to write to mdsal to exercise the sfc dataChangeListener */
         /* allow some time to let the impl code do it's work to push flows */
         /* or just comment out below lines and just manually verify on the bridges and reset them */
-        Thread.sleep(10000);
+        //Thread.sleep(10000);
 
-        Assert.assertTrue(southboundUtils.deleteBridge(connectionInfo, BRIDGE_NAME));
-        southboundUtils.disconnectOvsdbNode(connectionInfo);
+        assertTrue(southboundUtils.deleteBridge(connectionInfo, INTEGRATION_BRIDGE_NAME));
+        Thread.sleep(1000);
+        assertTrue(southboundUtils.disconnectOvsdbNode(connectionInfo));
     }
 }
index b7c0375e2f2e1bcfaa6124d1ec05137f55c4e9df..2119c4f54adfcc726c83c4307cf0691d959f234e 100644 (file)
@@ -25,6 +25,17 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
   <properties>
     <karaf.localFeature>odl-ovsdb-sfc-test</karaf.localFeature>
   </properties>
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>${project.groupId}</groupId>
+        <artifactId>openstack.net-virt-sfc-artifacts</artifactId>
+        <version>${project.version}</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
   <dependencies>
     <dependency>
       <!-- scope is compile so all features (there is only one) are installed