<sal.version>0.10.0-SNAPSHOT</sal.version>
<switchmanager.api.version>0.9.0-SNAPSHOT</switchmanager.api.version>
<yangtools.version>0.8.0-SNAPSHOT</yangtools.version>
- <!-- 3rd Pary Dependency Versions -->
- <commons.collection.version>1.0</commons.collection.version>
- <httpcomponents.version>4.2.1</httpcomponents.version>
- <portlet.version>2.0</portlet.version>
+ <!-- 3rd Party Dependency Versions -->
<powermock.version>1.5.2</powermock.version>
<dlux.version>0.3.0-SNAPSHOT</dlux.version>
<ovsdb.ui.version>0.1.0-SNAPSHOT</ovsdb.ui.version>
<type>pom</type>
<scope>import</scope>
</dependency>
- <dependency>
- <groupId>commons-collections</groupId>
- <artifactId>commons-collections</artifactId>
- <version>${commons.collection.version}</version>
- </dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>${netty.version}</version>
</dependency>
- <dependency>
- <groupId>javax.portlet</groupId>
- <artifactId>portlet-api</artifactId>
- <version>${portlet.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.httpcomponents</groupId>
- <artifactId>httpcore-nio</artifactId>
- <version>${httpcomponents.version}</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>commons.northbound</artifactId>
- <version>${northbound.commons.version}</version>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-api</artifactId>
<version>${controller.config.version}</version>
</dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>containermanager</artifactId>
- <version>${containermanager.version}</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>forwardingrulesmanager</artifactId>
- <version>${forwardingrulesmanager.version}</version>
- </dependency>
<dependency>
<groupId>org.opendaylight.neutron</groupId>
<artifactId>neutron-spi</artifactId>
<version>1.6.0-SNAPSHOT</version>
<type>zip</type>
</dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- <version>${sal.version}</version>
- </dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<scope>import</scope>
</dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>switchmanager</artifactId>
- <version>${switchmanager.api.version}</version>
- </dependency>
<dependency>
<groupId>org.opendaylight.openflowplugin.model</groupId>
<artifactId>model-flow-base</artifactId>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>features-parent</artifactId>
<version>1.6.0-SNAPSHOT</version>
- <relativePath></relativePath>
+ <relativePath/>
</parent>
<groupId>org.opendaylight.ovsdb</groupId>
<properties>
<odl.karaf.base.version>1.6.0-SNAPSHOT</odl.karaf.base.version>
<mdsal.version>1.3.0-SNAPSHOT</mdsal.version>
- <io.netty.version>3.8.0.Final</io.netty.version>
<networkconfig.neutron.version>0.6.0-SNAPSHOT</networkconfig.neutron.version>
<ovsdb.library.version>1.2.1-SNAPSHOT</ovsdb.library.version>
<openstack.netvirt.version>1.2.1-SNAPSHOT</openstack.netvirt.version>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
- <version>${commons.lang3.version}</version>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty</artifactId>
- <version>${io.netty.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-buffer</artifactId>
- <version>${netty.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-codec</artifactId>
- <version>${netty.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-codec-http</artifactId>
- <version>${netty.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-common</artifactId>
- <version>${netty.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-handler</artifactId>
- <version>${netty.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport</artifactId>
- <version>${netty.version}</version>
</dependency>
<dependency>
<groupId>equinoxSDK381</groupId>
<artifactId>javax.servlet</artifactId>
- <version>3.0.0.v201112011016</version>
</dependency>
<dependency>
<groupId>equinoxSDK381</groupId>
<artifactId>javax.servlet.jsp</artifactId>
- <version>2.2.0.v201112011158</version>
</dependency>
<dependency>
<groupId>equinoxSDK381</groupId>
<classifier>features</classifier>
<type>xml</type>
</dependency>
- <dependency>
- <groupId>org.opendaylight.ovsdb</groupId>
- <artifactId>ovsdb-ui-bundle</artifactId>
- <version>${ovsdb.ui.version}</version>
- </dependency>
</dependencies>
</project>
<features name="ovsdb-${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.openflowplugin/features-openflowplugin-extension/${openflowplugin.version}/xml/features</repository>
- <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin/${openflowplugin.version}/xml/features</repository>
- <repository>mvn:org.opendaylight.neutron/features-neutron/${networkconfig.neutron.version}/xml/features</repository>
+ <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin-extension/{{VERSION}}/xml/features</repository>
+ <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin/{{VERSION}}/xml/features</repository>
+ <repository>mvn:org.opendaylight.neutron/features-neutron/{{VERSION}}/xml/features</repository>
<repository>mvn:org.opendaylight.ovsdb/southbound-features/1.2.1-SNAPSHOT/xml/features</repository>
- <repository>mvn:org.opendaylight.controller/features-mdsal/${mdsal.version}/xml/features</repository>
- <repository>mvn:org.opendaylight.ovsdb/library-features/${ovsdb.library.version}/xml/features</repository>
- <repository>mvn:org.opendaylight.dlux/features-dlux/${dlux.version}/xml/features</repository>
+ <repository>mvn:org.opendaylight.controller/features-mdsal/{{VERSION}}/xml/features</repository>
+ <repository>mvn:org.opendaylight.ovsdb/library-features/{{VERSION}}/xml/features</repository>
+ <repository>mvn:org.opendaylight.dlux/features-dlux/{{VERSION}}/xml/features</repository>
<feature name="odl-ovsdb-all" description="OpenDaylight :: OVSDB :: all"
version='${project.version}'>
<feature name="odl-ovsdb-schema-openvswitch" description="OVSDB :: Schema :: Open_vSwitch"
version='${schema.openvswitch.version}'>
<feature version="${ovsdb.library.version}">odl-ovsdb-library</feature>
- <bundle>mvn:org.opendaylight.ovsdb/schema.openvswitch/${schema.openvswitch.version}</bundle>
+ <bundle>mvn:org.opendaylight.ovsdb/schema.openvswitch/{{VERSION}}</bundle>
</feature>
<feature name="odl-ovsdb-schema-hardwarevtep" description="OVSDB :: Schema :: hardware_vtep"
version='${schema.hardwarevtep.version}'>
<feature version="${ovsdb.library.version}">odl-ovsdb-library</feature>
- <bundle>mvn:org.opendaylight.ovsdb/schema.hardwarevtep/${schema.hardwarevtep.version}</bundle>
+ <bundle>mvn:org.opendaylight.ovsdb/schema.hardwarevtep/{{VERSION}}</bundle>
</feature>
<feature name="odl-ovsdb-openstack" description="OpenDaylight :: OVSDB :: OpenStack Network Virtualization"
<feature version='${mdsal.version}'>odl-mdsal-broker</feature>
<feature version="${openflowplugin.version}">odl-openflowplugin-nsf-model</feature>
<feature version="${networkconfig.neutron.version}">odl-neutron-service</feature>
- <feature version="1.2.1-SNAPSHOT">odl-ovsdb-southbound-impl-ui</feature>
+ <feature version="${project.version}">odl-ovsdb-southbound-impl-ui</feature>
<feature version="${openflowplugin.version}">odl-openflowplugin-flow-services</feature>
<feature version="${openflowplugin.version}">odl-openflowplugin-nxm-extensions</feature>
- <bundle>mvn:org.opendaylight.ovsdb/utils.servicehelper/${ovsdb.utils.servicehelper.version}</bundle>
- <bundle>mvn:org.opendaylight.ovsdb/utils.mdsal-utils/${project.version}</bundle>
- <bundle>mvn:org.opendaylight.ovsdb/openstack.net-virt/${openstack.netvirt.version}</bundle>
- <bundle>mvn:org.opendaylight.ovsdb/openstack.net-virt-providers/${openstack.netvirt.providers.version}</bundle>
- <bundle>mvn:org.opendaylight.neutron/dummyprovider/${networkconfig.neutron.version}</bundle>
- <configfile finalname="etc/opendaylight/karaf/netvirt-impl-default-config.xml">mvn:org.opendaylight.ovsdb/openstack.net-virt/${project.version}/xml/config</configfile>
- <configfile finalname="etc/opendaylight/karaf/netvirt-providers-impl-default-config.xml">mvn:org.opendaylight.ovsdb/openstack.net-virt-providers/${project.version}/xml/config</configfile>
+ <bundle>mvn:org.opendaylight.ovsdb/utils.servicehelper/{{VERSION}}</bundle>
+ <bundle>mvn:org.opendaylight.ovsdb/utils.mdsal-utils/{{VERSION}}</bundle>
+ <bundle>mvn:org.opendaylight.ovsdb/openstack.net-virt/{{VERSION}}</bundle>
+ <bundle>mvn:org.opendaylight.ovsdb/openstack.net-virt-providers/{{VERSION}}</bundle>
+ <bundle>mvn:org.opendaylight.neutron/dummyprovider/{{VERSION}}</bundle>
+ <configfile finalname="etc/opendaylight/karaf/netvirt-impl-default-config.xml">mvn:org.opendaylight.ovsdb/openstack.net-virt/{{VERSION}}/xml/config</configfile>
+ <configfile finalname="etc/opendaylight/karaf/netvirt-providers-impl-default-config.xml">mvn:org.opendaylight.ovsdb/openstack.net-virt-providers/{{VERSION}}/xml/config</configfile>
</feature>
<feature name="odl-ovsdb-ui" description="OpenDaylight :: OVSDB :: DLUX Integration Plugin" version='${ovsdb.ui.version}'>
<feature version="${dlux.version}">odl-dlux-core</feature>
- <bundle>mvn:org.opendaylight.ovsdb/ovsdb-ui-bundle/${ovsdb.ui.version}</bundle>
+ <bundle>mvn:org.opendaylight.ovsdb/ovsdb-ui-bundle/{{VERSION}}</bundle>
</feature>
</features>
<tag>HEAD</tag>
<url>https://wiki.opendaylight.org/view/OVSDB_Integration:Main</url>
</scm>
+
+ <properties>
+ <karaf.distro.groupId>org.opendaylight.ovsdb</karaf.distro.groupId>
+ <karaf.distro.artifactId>karaf</karaf.distro.artifactId>
+ <karaf.distro.version>${project.version}</karaf.distro.version>
+ <karaf.distro.type>zip</karaf.distro.type>
+ </properties>
+
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-util</artifactId>
</dependency>
- <!-- Dependencies for pax exam karaf container -->
- <dependency>
- <groupId>org.ops4j.pax.exam</groupId>
- <artifactId>pax-exam-container-karaf</artifactId>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.exam</groupId>
- <artifactId>pax-exam-junit4</artifactId>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.exam</groupId>
- <artifactId>pax-exam</artifactId>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.url</groupId>
- <artifactId>pax-url-aether</artifactId>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>javax.inject</groupId>
- <artifactId>javax.inject</artifactId>
- <version>1</version>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.karaf.features</groupId>
- <artifactId>org.apache.karaf.features.core</artifactId>
- <version>${karaf.version}</version>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <scope>compile</scope>
- </dependency>
<dependency>
<groupId>org.codehaus.sonar-plugins.java</groupId>
<artifactId>sonar-jacoco-listeners</artifactId>
<scope>test</scope>
</dependency>
- <!-- AbstractConfigTestBase::getKarafDistro() needs this to find its version -->
- <dependency>
- <groupId>org.opendaylight.ovsdb</groupId>
- <artifactId>karaf</artifactId>
- <version>${project.version}</version>
- <scope>test</scope>
- </dependency>
</dependencies>
<build>
<plugins>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
- <!-- Needed if you use versionAsInProject() -->
- <plugin>
- <groupId>org.apache.servicemix.tooling</groupId>
- <artifactId>depends-maven-plugin</artifactId>
- <version>1.2</version>
- <executions>
- <execution>
- <id>generate-depends-file</id>
- <goals>
- <goal>generate-depends-file</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
</plugins>
</build>
- <profiles>
- <profile>
- <id>default</id>
- <activation>
- <activeByDefault>true</activeByDefault>
- </activation>
- <properties>
- <skipITs>true</skipITs>
- </properties>
- </profile>
- <profile>
- <id>integrationtest</id>
- <activation>
- <activeByDefault>false</activeByDefault>
- </activation>
- <properties>
- <skipITs>false</skipITs>
- </properties>
- </profile>
- </profiles>
</project>
package org.opendaylight.ovsdb.openstack.netvirt.it;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.ops4j.pax.exam.CoreOptions.composite;
import static org.ops4j.pax.exam.CoreOptions.maven;
import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.propagateSystemProperties;
import static org.ops4j.pax.exam.CoreOptions.vmOption;
-import static org.ops4j.pax.exam.CoreOptions.when;
import static org.ops4j.pax.exam.CoreOptions.wrappedBundle;
import static org.ops4j.pax.exam.MavenUtils.asInProject;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.configureConsole;
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut;
-import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.karafDistributionConfiguration;
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.Lists;
-import java.io.File;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.UnknownHostException;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicBoolean;
-import javax.inject.Inject;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
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;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityServicesManager;
import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.PipelineOrchestrator;
import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
+import org.opendaylight.ovsdb.utils.config.ConfigProperties;
import org.opendaylight.ovsdb.utils.mdsal.openflow.FlowUtils;
import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
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.params.xml.ns.yang.ovsdb.rev150105.*;
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.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfoBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.InterfaceTypeEntryBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagerEntry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs;
+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.NodeId;
+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.TpId;
+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.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
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.KarafDistributionOption;
import org.ops4j.pax.exam.karaf.options.LogLevelOption;
import org.ops4j.pax.exam.options.MavenUrlReference;
import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
import org.ops4j.pax.exam.spi.reactors.PerClass;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static String addressStr;
private static String portStr;
private static String connectionType;
+ private static String controllerStr;
private static AtomicBoolean setup = new AtomicBoolean(false);
private static MdsalUtils mdsalUtils = null;
private static Southbound southbound = null;
- private static final String NETVIRT = "org.opendaylight.ovsdb.openstack.net-virt";
- private static final String NETVIRTPROVIDERS = "org.opendaylight.ovsdb.openstack.net-virt-providers";
-
- // TODO Constants copied frmo AbstractConfigTestBase, need to be removed (see TODO below)
- private static final String PAX_EXAM_UNPACK_DIRECTORY = "target/exam";
- private static final String KARAF_DEBUG_PORT = "5005";
- private static final String KARAF_DEBUG_PROP = "karaf.debug";
- private static final String KEEP_UNPACK_DIRECTORY_PROP = "karaf.keep.unpack";
-
- @Inject
- private BundleContext bundleContext;
-
- @Configuration
- public Option[] config() {
- // TODO Figure out how to use the parent Karaf setup, then just use super.config()
- Option[] options = new Option[] {
- when(Boolean.getBoolean(KARAF_DEBUG_PROP))
- .useOptions(KarafDistributionOption.debugConfiguration(KARAF_DEBUG_PORT, true)),
- karafDistributionConfiguration().frameworkUrl(getKarafDistro())
- .unpackDirectory(new File(PAX_EXAM_UNPACK_DIRECTORY))
- .useDeployFolder(false),
- when(Boolean.getBoolean(KEEP_UNPACK_DIRECTORY_PROP)).useOptions(keepRuntimeFolder()),
- // Works only if we don't specify the feature repo and name
- getLoggingOption()};
- Option[] propertyOptions = getPropertiesOptions();
- Option[] otherOptions = getOtherOptions();
- Option[] combinedOptions = new Option[options.length + propertyOptions.length + otherOptions.length];
- System.arraycopy(options, 0, combinedOptions, 0, options.length);
- System.arraycopy(propertyOptions, 0, combinedOptions, options.length, propertyOptions.length);
- System.arraycopy(otherOptions, 0, combinedOptions, options.length + propertyOptions.length,
- otherOptions.length);
- return combinedOptions;
- }
-
- private Option[] getOtherOptions() {
- return new Option[] {
- wrappedBundle(
- mavenBundle("org.opendaylight.ovsdb", "utils.mdsal-openflow")
- .version(asInProject())
- .type("jar")),
- vmOption("-javaagent:../jars/org.jacoco.agent.jar=destfile=../../jacoco-it.exec"),
- keepRuntimeFolder()
- };
- }
-
- @Override
- public String getKarafDistro() {
- return maven()
- .groupId("org.opendaylight.ovsdb")
- .artifactId("karaf")
- .versionAsInProject()
- .type("zip")
- .getURL();
- }
+ private static final String NETVIRT_TOPOLOGY_ID = "netvirt:1";
@Override
public String getModuleName() {
return "odl-ovsdb-openstack";
}
- protected String usage() {
- return "Integration Test needs a valid connection configuration as follows :\n"
- + "active connection : mvn -Dovsdbserver.ipaddress=x.x.x.x -Dovsdbserver.port=yyyy verify\n"
- + "passive connection : mvn -Dovsdbserver.connection=passive verify\n";
+ @Configuration
+ @Override
+ public Option[] config() {
+ Option[] parentOptions = super.config();
+ Option[] propertiesOptions = getPropertiesOptions();
+ Option[] otherOptions = getOtherOptions();
+ Option[] options = new Option[parentOptions.length + propertiesOptions.length + otherOptions.length];
+ System.arraycopy(parentOptions, 0, options, 0, parentOptions.length);
+ System.arraycopy(propertiesOptions, 0, options, parentOptions.length, propertiesOptions.length);
+ System.arraycopy(otherOptions, 0, options, parentOptions.length + propertiesOptions.length,
+ otherOptions.length);
+ return options;
+ }
+
+ private Option[] getOtherOptions() {
+ return new Option[] {
+ wrappedBundle(
+ mavenBundle("org.opendaylight.ovsdb", "utils.mdsal-openflow")
+ .version(asInProject())
+ .type("jar")),
+ wrappedBundle(
+ mavenBundle("org.opendaylight.ovsdb", "utils.config")
+ .version(asInProject())
+ .type("jar")),
+ configureConsole().startLocalConsole(),
+ vmOption("-javaagent:../jars/org.jacoco.agent.jar=destfile=../../jacoco-it.exec"),
+ keepRuntimeFolder()
+ };
+ }
+
+ public Option[] getPropertiesOptions() {
+ return new Option[] {
+ propagateSystemProperties(NetvirtITConstants.SERVER_IPADDRESS,
+ NetvirtITConstants.SERVER_PORT, NetvirtITConstants.CONNECTION_TYPE,
+ NetvirtITConstants.CONTROLLER_IPADDRESS),
+ };
}
@Override
editConfigurationFilePut(NetvirtITConstants.ORG_OPS4J_PAX_LOGGING_CFG,
"log4j.logger.org.opendaylight.ovsdb",
LogLevelOption.LogLevel.TRACE.name()),
- editConfigurationFilePut(NetvirtITConstants.ORG_OPS4J_PAX_LOGGING_CFG,
- "log4j.logger.org.opendaylight.ovsdb.lib",
+ editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
+ logConfiguration(NetvirtIT.class),
LogLevelOption.LogLevel.INFO.name()),
+ //editConfigurationFilePut(NetvirtITConstants.ORG_OPS4J_PAX_LOGGING_CFG,
+ // "log4j.logger.org.opendaylight.ovsdb.lib",
+ // LogLevelOption.LogLevel.INFO.name()),
super.getLoggingOption());
}
- private Option[] getPropertiesOptions() {
- Properties props = new Properties(System.getProperties());
- String addressStr = props.getProperty(NetvirtITConstants.SERVER_IPADDRESS,
- NetvirtITConstants.DEFAULT_SERVER_IPADDRESS);
- String portStr = props.getProperty(NetvirtITConstants.SERVER_PORT,
- NetvirtITConstants.DEFAULT_SERVER_PORT);
- String connectionType = props.getProperty(NetvirtITConstants.CONNECTION_TYPE,
- NetvirtITConstants.CONNECTION_TYPE_ACTIVE);
-
- LOG.info("getPropertiesOptions: Using the following properties: mode= {}, ip:port= {}:{}",
- connectionType, addressStr, portStr);
+ protected String usage() {
+ return "Integration Test needs a valid connection configuration as follows :\n"
+ + "active connection : mvn -Dovsdbserver.ipaddress=x.x.x.x -Dovsdbserver.port=yyyy verify\n"
+ + "passive connection : mvn -Dovsdbserver.connection=passive verify\n";
+ }
- return new Option[] {
- editConfigurationFilePut(NetvirtITConstants.CUSTOM_PROPERTIES,
- NetvirtITConstants.SERVER_IPADDRESS, addressStr),
- editConfigurationFilePut(NetvirtITConstants.CUSTOM_PROPERTIES,
- NetvirtITConstants.SERVER_PORT, portStr),
- editConfigurationFilePut(NetvirtITConstants.CUSTOM_PROPERTIES,
- NetvirtITConstants.CONNECTION_TYPE, connectionType),
- };
+ private void getProperties() {
+ Properties props = System.getProperties();
+ addressStr = props.getProperty(NetvirtITConstants.SERVER_IPADDRESS);
+ portStr = props.getProperty(NetvirtITConstants.SERVER_PORT, NetvirtITConstants.DEFAULT_SERVER_PORT);
+ connectionType = props.getProperty(NetvirtITConstants.CONNECTION_TYPE, "active");
+ controllerStr = props.getProperty(NetvirtITConstants.CONTROLLER_IPADDRESS);
+ LOG.info("setUp: Using the following properties: mode= {}, ip:port= {}:{}, controller ip: {}",
+ connectionType, addressStr, portStr, controllerStr);
+ if (connectionType.equalsIgnoreCase(NetvirtITConstants.CONNECTION_TYPE_ACTIVE)) {
+ if (addressStr == null) {
+ fail(usage());
+ }
+ }
}
@Before
e.printStackTrace();
}
- addressStr = bundleContext.getProperty(NetvirtITConstants.SERVER_IPADDRESS);
- portStr = bundleContext.getProperty(NetvirtITConstants.SERVER_PORT);
- connectionType = bundleContext.getProperty(NetvirtITConstants.CONNECTION_TYPE);
+ getProperties();
- LOG.info("setUp: Using the following properties: mode= {}, ip:port= {}:{}",
- connectionType, addressStr, portStr);
if (connectionType.equalsIgnoreCase(NetvirtITConstants.CONNECTION_TYPE_ACTIVE)) {
if (addressStr == null) {
fail(usage());
}
}
- isBundleReady(bundleContext, NETVIRT);
- isBundleReady(bundleContext, NETVIRTPROVIDERS);
-
- //dataBroker = getSession().getSALService(DataBroker.class);
- //Thread.sleep(3000);
- //dataBroker = OvsdbInventoryServiceImpl.getDataBroker();
- for (int i=0; i<20; i++) {
- southbound = (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
- if (southbound != null) {
- dataBroker = southbound.getDatabroker();
- if (dataBroker != null) {
- break;
+ dataBroker = getDatabroker(getProviderContext());
+ mdsalUtils = new MdsalUtils(dataBroker);
+ assertNotNull("mdsalUtils should not be null", mdsalUtils);
+ assertTrue("Did not find " + NETVIRT_TOPOLOGY_ID, getNetvirtTopology());
+ southbound = (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
+ assertNotNull("southbound should not be null", southbound);
+ setup.set(true);
+ }
+
+ private BindingAwareBroker.ProviderContext getProviderContext() {
+ BindingAwareBroker.ProviderContext providerContext = null;
+ for (int i=0; i < 60; i++) {
+ providerContext = getSession();
+ if (providerContext != null) {
+ break;
+ } else {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
}
}
- LOG.warn("NetvirtIT: dataBroker is null");
- Thread.sleep(5000);
}
- Assert.assertNotNull("dataBroker should not be null", dataBroker);
- Thread.sleep(5000);
-
- mdsalUtils = new MdsalUtils(dataBroker);
- setup.set(true);
+ assertNotNull("providercontext should not be null", providerContext);
+ /* One more second to let the provider finish initialization */
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ return providerContext;
+ }
+
+ private DataBroker getDatabroker(BindingAwareBroker.ProviderContext providerContext) {
+ DataBroker dataBroker = providerContext.getSALService(DataBroker.class);
+ assertNotNull("dataBroker should not be null", dataBroker);
+ 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;
}
/**
*
* @throws InterruptedException
*/
+ @Ignore
@Test
public void testPassiveNode() throws InterruptedException {
if (connectionType.equalsIgnoreCase(NetvirtITConstants.CONNECTION_TYPE_PASSIVE)) {
return true;
}
+ private String getControllerIPAddress() {
+ String addressString = ConfigProperties.getProperty(this.getClass(), "ovsdb.controller.address");
+ if (addressString != null) {
+ try {
+ if (InetAddress.getByName(addressString) != null) {
+ return addressString;
+ }
+ } catch (UnknownHostException e) {
+ LOG.error("Host {} is invalid", addressString);
+ }
+ }
+
+ addressString = ConfigProperties.getProperty(this.getClass(), "of.address");
+ if (addressString != null) {
+ try {
+ if (InetAddress.getByName(addressString) != null) {
+ return addressString;
+ }
+ } catch (UnknownHostException e) {
+ LOG.error("Host {} is invalid", addressString);
+ }
+ }
+
+ return null;
+ }
+
+ private short getControllerOFPort() {
+ short openFlowPort = Constants.OPENFLOW_PORT;
+ String portString = ConfigProperties.getProperty(this.getClass(), "of.listenPort");
+ if (portString != null) {
+ try {
+ openFlowPort = Short.parseShort(portString);
+ } catch (NumberFormatException e) {
+ LOG.warn("Invalid port:{}, use default({})", portString,
+ openFlowPort);
+ }
+ }
+ return openFlowPort;
+ }
+
+ private List<String> getControllersFromOvsdbNode(Node node) {
+ List<String> controllersStr = new ArrayList<>();
+
+ String controllerIpStr = getControllerIPAddress();
+ if (controllerIpStr != null) {
+ // If codepath makes it here, the ip address to be used was explicitly provided.
+ // Being so, also fetch openflowPort provided via ConfigProperties.
+ controllersStr.add(Constants.OPENFLOW_CONNECTION_PROTOCOL
+ + ":" + controllerIpStr + ":" + getControllerOFPort());
+ } else {
+ // Check if ovsdb node has manager entries
+ OvsdbNodeAugmentation ovsdbNodeAugmentation = southbound.extractOvsdbNode(node);
+ if (ovsdbNodeAugmentation != null) {
+ List<ManagerEntry> managerEntries = ovsdbNodeAugmentation.getManagerEntry();
+ if (managerEntries != null && !managerEntries.isEmpty()) {
+ for (ManagerEntry managerEntry : managerEntries) {
+ if (managerEntry == null || managerEntry.getTarget() == null) {
+ continue;
+ }
+ String[] tokens = managerEntry.getTarget().getValue().split(":");
+ if (tokens.length == 3 && tokens[0].equalsIgnoreCase("tcp")) {
+ controllersStr.add(Constants.OPENFLOW_CONNECTION_PROTOCOL
+ + ":" + tokens[1] + ":" + getControllerOFPort());
+ } else if (tokens[0].equalsIgnoreCase("ptcp")) {
+ ConnectionInfo connectionInfo = ovsdbNodeAugmentation.getConnectionInfo();
+ if (connectionInfo != null && connectionInfo.getLocalIp() != null) {
+ controllerIpStr = new String(connectionInfo.getLocalIp().getValue());
+ controllersStr.add(Constants.OPENFLOW_CONNECTION_PROTOCOL
+ + ":" + controllerIpStr + ":" + Constants.OPENFLOW_PORT);
+ } else {
+ LOG.warn("Ovsdb Node does not contain connection info: {}", node);
+ }
+ } else {
+ LOG.trace("Skipping manager entry {} for node {}",
+ managerEntry.getTarget(), node.getNodeId().getValue());
+ }
+ }
+ } else {
+ LOG.warn("Ovsdb Node does not contain manager entries : {}", node);
+ }
+ }
+ }
+
+ if (controllersStr.isEmpty()) {
+ // Neither user provided ip nor ovsdb node has manager entries. Lets use local machine ip address.
+ LOG.debug("Use local machine ip address as a OpenFlow Controller ip address");
+ controllerIpStr = getLocalControllerHostIpAddress();
+ if (controllerIpStr != null) {
+ controllersStr.add(Constants.OPENFLOW_CONNECTION_PROTOCOL
+ + ":" + controllerIpStr + ":" + Constants.OPENFLOW_PORT);
+ }
+ }
+
+ if (controllersStr.isEmpty()) {
+ LOG.warn("Failed to determine OpenFlow controller ip address");
+ } else if (LOG.isDebugEnabled()) {
+ controllerIpStr = "";
+ for (String currControllerIpStr : controllersStr) {
+ controllerIpStr += " " + currControllerIpStr;
+ }
+ LOG.debug("Found {} OpenFlow Controller(s) :{}", controllersStr.size(), controllerIpStr);
+ }
+
+ return controllersStr;
+ }
+
private String getLocalControllerHostIpAddress() {
String ipaddress = null;
try{
- for (Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces();
- ifaces.hasMoreElements();) {
+ for (Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces();ifaces.hasMoreElements();){
NetworkInterface iface = ifaces.nextElement();
for (Enumeration<InetAddress> inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements();) {
InetAddress inetAddr = inetAddrs.nextElement();
- if (!inetAddr.isLoopbackAddress()) {
- if (inetAddr.isSiteLocalAddress()) {
- ipaddress = inetAddr.getHostAddress();
- break;
- }
+ if (!inetAddr.isLoopbackAddress() && inetAddr.isSiteLocalAddress()) {
+ ipaddress = inetAddr.getHostAddress();
+ break;
}
}
}
}catch (Exception e){
- LOG.warn("Exception while fetching local host ip address ",e);
+ LOG.warn("Exception while fetching local host ip address ", e);
}
return ipaddress;
}
private String getControllerTarget(Node ovsdbNode) {
- String target = null;
- String ipAddr = null;
- OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
- ConnectionInfo connectionInfo = ovsdbNodeAugmentation.getConnectionInfo();
- LOG.info("connectionInfo: {}", connectionInfo);
- if (connectionInfo != null && connectionInfo.getLocalIp() != null) {
- ipAddr = new String(connectionInfo.getLocalIp().getValue());
- }
- if (ipAddr == null) {
- ipAddr = getLocalControllerHostIpAddress();
- }
-
- if (ipAddr != null) {
- target = NetvirtITConstants.OPENFLOW_CONNECTION_PROTOCOL + ":"
- + ipAddr + ":" + NetvirtITConstants.DEFAULT_OPENFLOW_PORT;
- }
-
- return target;
+ return getControllersFromOvsdbNode(ovsdbNode).get(0);
}
- //@Ignore//
@Test
public void testAddDeleteOvsdbNode() throws InterruptedException {
ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
bridge.getBridgeName());
}
- /**
- * isBundleReady is used to check if the requested bundle is Active
- */
- public void isBundleReady(BundleContext bundleContext, String bundleName) throws InterruptedException {
- boolean ready = false;
-
- while (!ready) {
- int state = Bundle.UNINSTALLED;
- Bundle[] bundles = bundleContext.getBundles();
- for (Bundle element : bundles) {
- if (element.getSymbolicName().equals(bundleName)) {
- state = element.getState();
- LOG.info(">>>>> bundle is ready {}", bundleName);
- break;
- }
- }
- if (state != Bundle.ACTIVE) {
- LOG.info(">>>>> bundle not ready {}", bundleName);
- Thread.sleep(5000);
- } else {
- ready = true;
- }
- }
- }
-
private void netVirtAddPort(ConnectionInfo connectionInfo) throws InterruptedException {
OvsdbBridgeAugmentation bridge = getBridge(connectionInfo, NetvirtITConstants.INTEGRATION_BRIDGE_NAME);
Assert.assertNotNull(bridge);
* </pre>
* @throws InterruptedException
*/
- // TODO add verification of flows
- //@Ignore //
+ @Ignore
@Test
public void testNetVirt() throws InterruptedException {
ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
Node ovsdbNode = connectOvsdbNode(connectionInfo);
- Thread.sleep(10000);
+ Thread.sleep(30000);
// Verify the pipeline flows were installed
PipelineOrchestrator pipelineOrchestrator =
(PipelineOrchestrator) ServiceHelper.getGlobalInstance(PipelineOrchestrator.class, this);
assertNotNull("Could not find PipelineOrchestrator Service", pipelineOrchestrator);
Node bridgeNode = southbound.getBridgeNode(ovsdbNode, NetvirtITConstants.INTEGRATION_BRIDGE_NAME);
assertNotNull("bridge " + NetvirtITConstants.INTEGRATION_BRIDGE_NAME + " was not found", bridgeNode);
+ LOG.info("testNetVirt: bridgeNode: {}", bridgeNode);
long datapathId = southbound.getDataPathId(bridgeNode);
+ assertNotEquals("datapathId was not found", datapathId, 0);
org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder nodeBuilder =
FlowUtils.createNodeBuilder(datapathId);
Thread.sleep(60000);
}
+ @Ignore
@Test
public void testReadOvsdbTopologyNodes() throws InterruptedException {
Thread.sleep(10000);
public static final String CUSTOM_PROPERTIES = "etc/custom.properties";
public static final String SERVER_IPADDRESS = "ovsdbserver.ipaddress";
public static final String SERVER_PORT = "ovsdbserver.port";
+ public static final String CONTROLLER_IPADDRESS = "ovsdb.controller.address";
public static final String SERVER_EXTRAS = "ovsdbserver.extras";
public static final String CONNECTION_TYPE = "ovsdbserver.connection";
public static final String CONNECTION_TYPE_ACTIVE = "active";
public static String createDatapathType(OvsdbBridgeAugmentation mdsalbridge) {
String datapathtype = SouthboundConstants.DATAPATH_TYPE_MAP.get(DatapathTypeSystem.class);
- if (mdsalbridge.getDatapathType() != null) {
- if (SouthboundConstants.DATAPATH_TYPE_MAP.get(mdsalbridge.getDatapathType()) != null) {
- datapathtype = SouthboundConstants.DATAPATH_TYPE_MAP.get(mdsalbridge.getDatapathType());
- } else {
- throw new IllegalArgumentException("Unknown datapath type "
- + SouthboundConstants.DATAPATH_TYPE_MAP.get(mdsalbridge.getDatapathType()));
+ if (mdsalbridge.getDatapathType() != null && !mdsalbridge.getDatapathType().equals(DatapathTypeBase.class)) {
+ datapathtype = SouthboundConstants.DATAPATH_TYPE_MAP.get(mdsalbridge.getDatapathType());
+ if (datapathtype == null) {
+ throw new IllegalArgumentException("Unknown datapath type " + mdsalbridge.getDatapathType().getName());
}
}
return datapathtype;
* http://docs.openstack.org/api/openstack-network/2.0/content/security_groups.html
*
*/
+
+ if (portSecurityRule == null ||
+ portSecurityRule.getSecurityRuleEthertype() == null ||
+ portSecurityRule.getSecurityRuleDirection() == null) {
+ continue;
+ }
+
if ("IPv4".equals(portSecurityRule.getSecurityRuleEthertype())
&& portSecurityRule.getSecurityRuleDirection().equals("egress")) {
LOG.debug("programPortSecurityGroup: Acl Rule matching IPv4 and ingress is: {} ", portSecurityRule);
Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
break;
default:
- LOG.error("programPortSecurityRule: Protocol not supported", portSecurityRule);
+ LOG.info("programPortSecurityAcl: Protocol is not TCP/UDP/ICMP but other " +
+ "protocol = ", portSecurityRule.getSecurityRuleProtocol());
+ egressOtherProtocolAclHandler(dpid, segmentationId, attachedMac,
+ portSecurityRule, ipaddress, write,
+ Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
break;
}
}
}
+ private void egressOtherProtocolAclHandler(Long dpidLong, String segmentationId, String srcMac,
+ NeutronSecurityRule portSecurityRule, String dstAddress,
+ boolean write, Integer protoPortMatchPriority) {
+
+ MatchBuilder matchBuilder = new MatchBuilder();
+ String flowId = "Egress_Other_" + segmentationId + "_" + srcMac + "_";
+ matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,srcMac,null);
+
+ short proto = 0;
+ try {
+ Integer protocol = new Integer(portSecurityRule.getSecurityRuleProtocol());
+ proto = protocol.shortValue();
+ flowId = flowId + proto;
+ } catch (NumberFormatException e) {
+ LOG.error("Protocol vlaue conversion failure", e);
+ }
+ matchBuilder = MatchUtils.createIpProtocolMatch(matchBuilder, proto);
+
+ if (null != dstAddress) {
+ flowId = flowId + dstAddress;
+ matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,null,
+ MatchUtils.iPv4PrefixFromIPv4Address(dstAddress));
+
+ } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
+ flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
+ matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder, null,new Ipv4Prefix(portSecurityRule
+ .getSecurityRuleRemoteIpPrefix()));
+ }
+ flowId = flowId + "_Permit";
+ String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
+ NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
+ syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
+ }
+
@Override
public void programFixedSecurityGroup(Long dpid, String segmentationId, String attachedMac,
long localPort, List<Neutron_IPs> srcAddressList,
if (portSecurityRule.getSecurityRulePortMin().equals(PORT_RANGE_MIN)
&& portSecurityRule.getSecurityRulePortMax().equals(PORT_RANGE_MAX)) {
flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_"
- + portSecurityRule.getSecurityRulePortMax() + "_";
+ + portSecurityRule.getSecurityRulePortMax() + "_";
matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.TCP_SHORT, 0, 0);
}
/*TODO TCP PortRange Match*/
if (null != dstAddress) {
flowId = flowId + dstAddress;
matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,null,
- MatchUtils.iPv4PrefixFromIPv4Address(dstAddress));
+ MatchUtils.iPv4PrefixFromIPv4Address(dstAddress));
} else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,null,
- new Ipv4Prefix(portSecurityRule
- .getSecurityRuleRemoteIpPrefix()));
+ new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()));
}
flowId = flowId + "_Permit";
String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
private void egressAclIcmp(Long dpidLong, String segmentationId, String srcMac,
NeutronSecurityRule portSecurityRule, String dstAddress,
boolean write, Integer protoPortMatchPriority) {
+
MatchBuilder matchBuilder = new MatchBuilder();
- String flowId = "Egress_ICMP_" + segmentationId + "_" + srcMac + "_"
- + portSecurityRule.getSecurityRulePortMin().shortValue() + "_"
- + portSecurityRule.getSecurityRulePortMax().shortValue() + "_";
+ String flowId = "Egress_ICMP_" + segmentationId + "_" + srcMac + "_";
matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,srcMac,null);
- matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,
- portSecurityRule.getSecurityRulePortMin().shortValue(),
- portSecurityRule.getSecurityRulePortMax().shortValue());
+ /*Custom ICMP Match */
+ if (portSecurityRule.getSecurityRulePortMin() != null &&
+ portSecurityRule.getSecurityRulePortMax() != null) {
+ flowId = flowId + portSecurityRule.getSecurityRulePortMin().shortValue() + "_"
+ + portSecurityRule.getSecurityRulePortMax().shortValue() + "_";
+ matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,
+ portSecurityRule.getSecurityRulePortMin().shortValue(),
+ portSecurityRule.getSecurityRulePortMax().shortValue());
+ } else {
+ /* All ICMP Match */ // We are getting from neutron NULL for both min and max
+ flowId = flowId + "all" + "_" ;
+ matchBuilder = MatchUtils.createICMPv4Match(matchBuilder, MatchUtils.ALL_ICMP, MatchUtils.ALL_ICMP);
+ }
if (null != dstAddress) {
flowId = flowId + dstAddress;
matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,null,
*
*/
+ if (portSecurityRule == null ||
+ portSecurityRule.getSecurityRuleEthertype() == null ||
+ portSecurityRule.getSecurityRuleDirection() == null) {
+ continue;
+ }
+
if ("IPv4".equals(portSecurityRule.getSecurityRuleEthertype())
&& "ingress".equals(portSecurityRule.getSecurityRuleDirection())) {
LOG.debug("programPortSecurityGroup: Rule matching IPv4 and ingress is: {} ", portSecurityRule);
securityGroupCacheManger.portRemoved(securityGroup.getSecurityGroupUUID(), portUuid);
}
}
-
-
-
}
}
write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
break;
default:
- LOG.error("programPortSecurityRule: Protocol not supported", portSecurityRule);
+ LOG.info("programPortSecurityAcl: Protocol is not TCP/UDP/ICMP but other " +
+ "protocol = ", portSecurityRule.getSecurityRuleProtocol());
+ ingressOtherProtocolAclHandler(dpid, segmentationId, attachedMac, portSecurityRule,
+ null, write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
break;
}
}
}
+ private void ingressOtherProtocolAclHandler(Long dpidLong, String segmentationId, String dstMac,
+ NeutronSecurityRule portSecurityRule, String srcAddress,
+ boolean write, Integer protoPortMatchPriority) {
+
+ MatchBuilder matchBuilder = new MatchBuilder();
+ String flowId = "Ingress_Other_" + segmentationId + "_" + dstMac + "_";
+ matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
+ short proto = 0;
+ try {
+ Integer protocol = new Integer(portSecurityRule.getSecurityRuleProtocol());
+ proto = protocol.shortValue();
+ flowId = flowId + proto;
+ } catch (NumberFormatException e) {
+ LOG.error("Protocol vlaue conversion failure", e);
+ }
+ matchBuilder = MatchUtils.createIpProtocolMatch(matchBuilder, proto);
+ if (null != srcAddress) {
+ flowId = flowId + srcAddress;
+ matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
+ MatchUtils.iPv4PrefixFromIPv4Address(srcAddress), null);
+ } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
+ flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
+ matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
+ new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()),null);
+ }
+ String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
+ NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
+ flowId = flowId + "_Permit";
+ syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
+ }
+
@Override
public void programFixedSecurityGroup(Long dpid, String segmentationId, String dhcpMacAddress,
long localPort, boolean isLastPortinSubnet,
boolean write, Integer protoPortMatchPriority) {
MatchBuilder matchBuilder = new MatchBuilder();
- FlowBuilder flowBuilder = new FlowBuilder();
- String flowId = "Ingress_ICMP_" + segmentationId + "_" + dstMac + "_"
- + portSecurityRule.getSecurityRulePortMin().shortValue() + "_"
- + portSecurityRule.getSecurityRulePortMax().shortValue() + "_";
+ String flowId = "Ingress_ICMP_" + segmentationId + "_" + dstMac + "_";
matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
- matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,
- portSecurityRule.getSecurityRulePortMin().shortValue(),
- portSecurityRule.getSecurityRulePortMax().shortValue());
+
+ /* Custom ICMP Match */
+ if (portSecurityRule.getSecurityRulePortMin() != null &&
+ portSecurityRule.getSecurityRulePortMax() != null) {
+ flowId = flowId + portSecurityRule.getSecurityRulePortMin().shortValue() + "_"
+ + portSecurityRule.getSecurityRulePortMax().shortValue() + "_";
+ matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,
+ portSecurityRule.getSecurityRulePortMin().shortValue(),
+ portSecurityRule.getSecurityRulePortMax().shortValue());
+ } else {
+ /* All ICMP Match */
+ flowId = flowId + "all" + "_";
+ matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,MatchUtils.ALL_ICMP, MatchUtils.ALL_ICMP);
+ }
if (null != srcAddress) {
flowId = flowId + srcAddress;
matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
package org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services;
import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import org.opendaylight.ovsdb.openstack.netvirt.api.L2ForwardingProvider;
import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
import org.opendaylight.ovsdb.utils.mdsal.openflow.ActionUtils;
+import org.opendaylight.ovsdb.utils.mdsal.openflow.FlowUtils;
import org.opendaylight.ovsdb.utils.mdsal.openflow.InstructionUtils;
import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
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.Instructions;
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.instruction.ApplyActionsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActions;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
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.inventory.rev130819.NodeConnectorId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxRegCaseBuilder;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.collect.Lists;
-
public class L2ForwardingService extends AbstractServiceInstance implements ConfigInterface, L2ForwardingProvider {
private static final Logger LOG = LoggerFactory.getLogger(L2ForwardingService.class);
public L2ForwardingService() {
String nodeName = OPENFLOW + dpidLong;
- MatchBuilder matchBuilder = new MatchBuilder();
NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
FlowBuilder flowBuilder = new FlowBuilder();
// Create the OF Match using MatchBuilder
- flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
- flowBuilder.setMatch(MatchUtils.createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
+ MatchBuilder matchBuilder = new MatchBuilder();
+ MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId));
+ MatchUtils.createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null);
+ flowBuilder.setMatch(matchBuilder.build());
- String flowId = "UcastOut_"+segmentationId+"_"+localPort+"_"+attachedMac;
// Add Flow Attributes
- flowBuilder.setId(new FlowId(flowId));
- FlowKey key = new FlowKey(new FlowId(flowId));
- flowBuilder.setStrict(true);
- flowBuilder.setBarrier(false);
- flowBuilder.setTableId(getTable());
- flowBuilder.setKey(key);
- flowBuilder.setFlowName(flowId);
- flowBuilder.setHardTimeout(0);
- flowBuilder.setIdleTimeout(0);
+ String flowName = "UcastOut_" + segmentationId + "_" + localPort + "_" + attachedMac;
+ FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable());
if (write) {
- // Instantiate the Builders for the OF Actions and Instructions
- InstructionBuilder ib = new InstructionBuilder();
- InstructionsBuilder isb = new InstructionsBuilder();
-
- // Instructions List Stores Individual Instructions
- List<Instruction> instructions = Lists.newArrayList();
-
// Set the Output Port/Iface
- InstructionUtils.createOutputPortInstructions(ib, dpidLong, localPort);
- ib.setOrder(0);
- ib.setKey(new InstructionKey(0));
- instructions.add(ib.build());
-
- // Add InstructionBuilder to the Instruction(s)Builder List
- isb.setInstruction(instructions);
+ Instruction setOutputPortInstruction =
+ InstructionUtils.createOutputPortInstructions(new InstructionBuilder(), dpidLong, localPort)
+ .setOrder(0)
+ .setKey(new InstructionKey(0))
+ .build();
// Add InstructionsBuilder to FlowBuilder
- flowBuilder.setInstructions(isb.build());
+ InstructionUtils.setFlowBuilderInstruction(flowBuilder, setOutputPortInstruction);
writeFlow(flowBuilder, nodeBuilder);
} else {
removeFlow(flowBuilder, nodeBuilder);
}
}
+
/*
* (Table:2) Local VLAN unicast
* Match: VLAN ID and dMAC
String nodeName = OPENFLOW + dpidLong;
- MatchBuilder matchBuilder = new MatchBuilder();
NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
FlowBuilder flowBuilder = new FlowBuilder();
// Create the OF Match using MatchBuilder
- flowBuilder.setMatch(
- MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId)), true).build());
- flowBuilder.setMatch(MatchUtils.createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
+ MatchBuilder matchBuilder = new MatchBuilder();
+ MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId)), true);
+ MatchUtils.createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null);
+ flowBuilder.setMatch(matchBuilder.build());
- String flowId = "VlanUcastOut_"+segmentationId+"_"+localPort+"_"+attachedMac;
// Add Flow Attributes
- flowBuilder.setId(new FlowId(flowId));
- FlowKey key = new FlowKey(new FlowId(flowId));
- flowBuilder.setStrict(true);
- flowBuilder.setBarrier(false);
- flowBuilder.setTableId(getTable());
- flowBuilder.setKey(key);
- flowBuilder.setFlowName(flowId);
- flowBuilder.setHardTimeout(0);
- flowBuilder.setIdleTimeout(0);
+ String flowName = "VlanUcastOut_" + segmentationId + "_" + localPort + "_" + attachedMac;
+ FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable());
if (write) {
- // Instantiate the Builders for the OF Actions and Instructions
- InstructionBuilder ib = new InstructionBuilder();
- InstructionsBuilder isb = new InstructionsBuilder();
-
- // Instructions List Stores Individual Instructions
- List<Instruction> instructions = Lists.newArrayList();
- List<Instruction> instructions_tmp = Lists.newArrayList();
-
/* Strip vlan and store to tmp instruction space*/
- InstructionUtils.createPopVlanInstructions(ib);
- ib.setOrder(0);
- ib.setKey(new InstructionKey(0));
- instructions_tmp.add(ib.build());
+ Instruction stripVlanInstruction = InstructionUtils.createPopVlanInstructions(new InstructionBuilder())
+ .setOrder(0)
+ .setKey(new InstructionKey(0))
+ .build();
// Set the Output Port/Iface
- ib = new InstructionBuilder();
- InstructionUtils.addOutputPortInstructions(ib, dpidLong, localPort, instructions_tmp);
- ib.setOrder(1);
- ib.setKey(new InstructionKey(0));
- instructions.add(ib.build());
-
- // Add InstructionBuilder to the Instruction(s)Builder List
- isb.setInstruction(instructions);
+ Instruction setOutputPortInstruction =
+ InstructionUtils.addOutputPortInstructions(new InstructionBuilder(), dpidLong, localPort,
+ Collections.singletonList(stripVlanInstruction))
+ .setOrder(1)
+ .setKey(new InstructionKey(0))
+ .build();
// Add InstructionsBuilder to FlowBuilder
- flowBuilder.setInstructions(isb.build());
+ InstructionUtils.setFlowBuilderInstruction(flowBuilder, setOutputPortInstruction);
writeFlow(flowBuilder, nodeBuilder);
} else {
removeFlow(flowBuilder, nodeBuilder);
}
- /**
- * Utility function used by the flooding logic to allow a flow to be resubmitted
- * to the local port flooding rule, after being outputed to all available tunnel
- * or VLAN egress ports.
- */
- private void appendResubmitLocalFlood(InstructionBuilder ib) {
-
- //Update the ApplyActions instructions
- ApplyActionsCase aac = (ApplyActionsCase) ib.getInstruction();
- List<Action> actionList = aac.getApplyActions().getAction();
-
- int index = actionList.size();
- ActionBuilder ab = new ActionBuilder();
- ab.setAction(ActionUtils.nxLoadRegAction(new DstNxRegCaseBuilder().setNxReg(ClassifierService.REG_FIELD).build(),
- BigInteger.valueOf(ClassifierService.REG_VALUE_FROM_REMOTE)));
- ab.setOrder(index);
- ab.setKey(new ActionKey(index));
- actionList.add(ab.build());
-
- index++;
- ab = new ActionBuilder();
- ab.setAction(ActionUtils.nxResubmitAction(null, this.getTable()));
- ab.setOrder(index);
- ab.setKey(new ActionKey(index));
- actionList.add(ab.build());
- }
-
/*
* (Table:2) Local Broadcast Flood
* Match: Tunnel ID and dMAC (::::FF:FF)
String nodeName = OPENFLOW + dpidLong;
- MatchBuilder matchBuilder = new MatchBuilder();
NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
FlowBuilder flowBuilder = new FlowBuilder();
// Create the OF Match using MatchBuilder
- MatchUtils.addNxRegMatch(matchBuilder, new MatchUtils.RegMatch(ClassifierService.REG_FIELD, ClassifierService.REG_VALUE_FROM_REMOTE));
- flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
- flowBuilder.setMatch(MatchUtils.createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"),
- new MacAddress("01:00:00:00:00:00")).build());
+ MatchBuilder matchBuilder = new MatchBuilder();
+ MatchUtils.addNxRegMatch(matchBuilder,
+ new MatchUtils.RegMatch(ClassifierService.REG_FIELD, ClassifierService.REG_VALUE_FROM_REMOTE));
+ MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId));
+ MatchUtils.createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"),
+ new MacAddress("01:00:00:00:00:00"));
+ flowBuilder.setMatch(matchBuilder.build());
- String flowId = "BcastOut_"+segmentationId;
// Add Flow Attributes
- flowBuilder.setId(new FlowId(flowId));
- FlowKey key = new FlowKey(new FlowId(flowId));
- flowBuilder.setStrict(true);
- flowBuilder.setBarrier(false);
- flowBuilder.setTableId(getTable());
- flowBuilder.setKey(key);
- flowBuilder.setPriority(16384);
- flowBuilder.setFlowName(flowId);
- flowBuilder.setHardTimeout(0);
- flowBuilder.setIdleTimeout(0);
+ String flowName = "BcastOut_" + segmentationId;
+ FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable())
+ .setPriority(16384);
+
Flow flow = this.getFlow(flowBuilder, nodeBuilder);
- // Instantiate the Builders for the OF Actions and Instructions
- InstructionBuilder ib = new InstructionBuilder();
- InstructionsBuilder isb = new InstructionsBuilder();
- List<Instruction> instructions = Lists.newArrayList();
- List<Instruction> existingInstructions = null;
- if (flow != null) {
- Instructions ins = flow.getInstructions();
- if (ins != null) {
- existingInstructions = ins.getInstruction();
- }
- }
+
+ // Retrieve the existing instructions
+ List<Instruction> existingInstructions = InstructionUtils.extractExistingInstructions(flow);
if (write) {
// Create output port list
- createOutputPortInstructions(ib, dpidLong, localPort, existingInstructions);
- ib.setOrder(0);
- ib.setKey(new InstructionKey(0));
+ Instruction outputPortInstruction =
+ createOutputPortInstructions(new InstructionBuilder(), dpidLong, localPort, existingInstructions)
+ .setOrder(0)
+ .setKey(new InstructionKey(0))
+ .build();
- /* Alternative method to address Bug 2004 is to make a call
- * here to appendResubmitLocalFlood(ib) so that we send the
- * flow back to the local flood rule.
- */
- instructions.add(ib.build());
-
- // Add InstructionBuilder to the Instruction(s)Builder List
- isb.setInstruction(instructions);
+ /* Alternative method to address Bug 2004 is to use appendResubmitLocalFlood(ib) so that we send the
+ * flow back to the local flood rule. (See git history.) */
// Add InstructionsBuilder to FlowBuilder
- flowBuilder.setInstructions(isb.build());
+ InstructionUtils.setFlowBuilderInstruction(flowBuilder, outputPortInstruction);
writeFlow(flowBuilder, nodeBuilder);
} else {
+ InstructionBuilder ib = new InstructionBuilder();
boolean flowRemove = InstructionUtils.removeOutputPortFromInstructions(ib, dpidLong, localPort,
existingInstructions);
if (flowRemove) {
removeFlow(flowBuilder, nodeBuilder);
} else {
/* Install instruction with new output port list*/
- ib.setOrder(0);
- ib.setKey(new InstructionKey(0));
- instructions.add(ib.build());
-
- // Add InstructionBuilder to the Instruction(s)Builder List
- isb.setInstruction(instructions);
+ Instruction outputPortInstruction = ib
+ .setOrder(0)
+ .setKey(new InstructionKey(0))
+ .build();
// Add InstructionsBuilder to FlowBuilder
- flowBuilder.setInstructions(isb.build());
+ InstructionUtils.setFlowBuilderInstruction(flowBuilder, outputPortInstruction);
+
writeFlow(flowBuilder, nodeBuilder);
}
}
String nodeName = OPENFLOW + dpidLong;
- MatchBuilder matchBuilder = new MatchBuilder();
NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
FlowBuilder flowBuilder = new FlowBuilder();
// Create the OF Match using MatchBuilder
- flowBuilder.setMatch(
- MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId)), true).build());
- flowBuilder.setMatch(MatchUtils.createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"),
- new MacAddress("01:00:00:00:00:00")).build());
+ MatchBuilder matchBuilder = new MatchBuilder();
+ MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId)), true);
+ MatchUtils.createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"),
+ new MacAddress("01:00:00:00:00:00"));
+ flowBuilder.setMatch(matchBuilder.build());
- String flowId = "VlanBcastOut_"+segmentationId+"_"+ethPort;
// Add Flow Attributes
- flowBuilder.setId(new FlowId(flowId));
- FlowKey key = new FlowKey(new FlowId(flowId));
- flowBuilder.setStrict(true);
- flowBuilder.setBarrier(false);
- flowBuilder.setTableId(getTable());
- flowBuilder.setKey(key);
- flowBuilder.setPriority(16384);
- flowBuilder.setFlowName(flowId);
- flowBuilder.setHardTimeout(0);
- flowBuilder.setIdleTimeout(0);
+ String flowName = "VlanBcastOut_" + segmentationId + "_" + ethPort;
+ FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable())
+ .setPriority(16384);
Flow flow = this.getFlow(flowBuilder, nodeBuilder);
- // Instantiate the Builders for the OF Actions and Instructions
- List<Instruction> existingInstructions = null;
- if (flow != null) {
- Instructions ins = flow.getInstructions();
- if (ins != null) {
- existingInstructions = ins.getInstruction();
- }
- }
- List<Instruction> instructions = Lists.newArrayList();
- InstructionBuilder ib = new InstructionBuilder();
- List<Action> actionList;
+ // Retrieve the existing instructions
+ List<Instruction> existingInstructions = InstructionUtils.extractExistingInstructions(flow);
+
if (write) {
- if (existingInstructions == null) {
+ List<Action> actionList;
+ if (existingInstructions == null || existingInstructions.isEmpty()) {
/* First time called there should be no instructions.
* We can simply add the output:ethPort first, followed by
* popVlan and then the local port. The next calls will append
* the rest of the local ports.
*/
- ActionBuilder ab = new ActionBuilder();
- actionList = Lists.newArrayList();
-
- ab.setAction(ActionUtils.outputAction(new NodeConnectorId(nodeName + ":" + ethPort)));
- ab.setOrder(0);
- ab.setKey(new ActionKey(0));
- actionList.add(ab.build());
-
- ab.setAction(ActionUtils.popVlanAction());
- ab.setOrder(1);
- ab.setKey(new ActionKey(1));
- actionList.add(ab.build());
-
- ab.setAction(ActionUtils.outputAction(new NodeConnectorId(nodeName + ":" + localPort)));
- ab.setOrder(2);
- ab.setKey(new ActionKey(2));
- actionList.add(ab.build());
+ actionList = new ArrayList<>();
+
+ actionList.add(
+ new ActionBuilder()
+ .setAction(ActionUtils.outputAction(new NodeConnectorId(nodeName + ":" + ethPort)))
+ .setOrder(0)
+ .setKey(new ActionKey(0))
+ .build());
+
+ actionList.add(
+ new ActionBuilder()
+ .setAction(ActionUtils.popVlanAction())
+ .setOrder(1)
+ .setKey(new ActionKey(1))
+ .build());
+
+ actionList.add(
+ new ActionBuilder()
+ .setAction(ActionUtils.outputAction(new NodeConnectorId(nodeName + ":" + localPort)))
+ .setOrder(2)
+ .setKey(new ActionKey(2))
+ .build());
} else {
/* Subsequent calls require appending any new local ports for this tenant. */
Instruction in = existingInstructions.get(0);
actionList = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
NodeConnectorId ncid = new NodeConnectorId(nodeName + ":" + localPort);
+ final Uri nodeConnectorUri = new Uri(ncid);
boolean addNew = true;
/* Check if the port is already in the output list */
for (Action action : actionList) {
if (action.getAction() instanceof OutputActionCase) {
OutputActionCase opAction = (OutputActionCase) action.getAction();
- if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
+ if (opAction.getOutputAction().getOutputNodeConnector().equals(nodeConnectorUri)) {
addNew = false;
break;
}
}
if (addNew) {
- ActionBuilder ab = new ActionBuilder();
-
- ab.setAction(ActionUtils.outputAction(new NodeConnectorId(nodeName + ":" + localPort)));
- ab.setOrder(actionList.size());
- ab.setKey(new ActionKey(actionList.size()));
- actionList.add(ab.build());
+ actionList.add(
+ new ActionBuilder()
+ .setAction(
+ ActionUtils.outputAction(new NodeConnectorId(nodeName + ":" + localPort)))
+ .setOrder(actionList.size())
+ .setKey(new ActionKey(actionList.size()))
+ .build());
}
}
- ApplyActionsBuilder aab = new ApplyActionsBuilder();
- aab.setAction(actionList);
- ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
- ib.setOrder(0);
- ib.setKey(new InstructionKey(0));
- instructions.add(ib.build());
-
- // Add InstructionBuilder to the Instruction(s)Builder List
- InstructionsBuilder isb = new InstructionsBuilder();
- isb.setInstruction(instructions);
+ ApplyActions applyActions = new ApplyActionsBuilder().setAction(actionList).build();
+ Instruction applyActionsInstruction =
+ new InstructionBuilder()
+ .setInstruction(new ApplyActionsCaseBuilder().setApplyActions(applyActions).build())
+ .setOrder(0)
+ .setKey(new InstructionKey(0))
+ .build();
// Add InstructionsBuilder to FlowBuilder
- flowBuilder.setInstructions(isb.build());
+ InstructionUtils.setFlowBuilderInstruction(flowBuilder, applyActionsInstruction);
writeFlow(flowBuilder, nodeBuilder);
} else {
- //boolean flowRemove = removeOutputPortFromGroup(nodeBuilder, ib, dpidLong,
- // localPort, existingInstructions);
+ InstructionBuilder ib = new InstructionBuilder();
boolean flowRemove = removeOutputPortFromInstructions(ib, dpidLong, localPort, ethPort,
existingInstructions);
if (flowRemove) {
removeFlow(flowBuilder, nodeBuilder);
} else {
/* Install instruction with new output port list*/
- ib.setOrder(0);
- ib.setKey(new InstructionKey(0));
- instructions.add(ib.build());
-
- // Add InstructionBuilder to the Instruction(s)Builder List
- InstructionsBuilder isb = new InstructionsBuilder();
- isb.setInstruction(instructions);
+ Instruction outputPortInstruction = ib
+ .setOrder(0)
+ .setKey(new InstructionKey(0))
+ .build();
// Add InstructionsBuilder to FlowBuilder
- flowBuilder.setInstructions(isb.build());
+ InstructionUtils.setFlowBuilderInstruction(flowBuilder, outputPortInstruction);
writeFlow(flowBuilder, nodeBuilder);
}
}
private boolean removeOutputPortFromInstructions(InstructionBuilder ib, Long dpidLong, Long localPort,
Long ethPort, List<Instruction> instructions) {
- List<Action> actionList = Lists.newArrayList();
+ List<Action> actionList = new ArrayList<>();
boolean removeFlow = true;
- if (instructions != null) {
+ if (instructions != null && !instructions.isEmpty()) {
Instruction in = instructions.get(0);
List<Action> oldActionList = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
NodeConnectorId ncid = new NodeConnectorId(OPENFLOW + dpidLong + ":" + localPort);
+ final Uri localNodeConnectorUri = new Uri(ncid);
NodeConnectorId ncidEth = new NodeConnectorId(OPENFLOW + dpidLong + ":" + ethPort);
+ final Uri ethNodeConnectorUri = new Uri(ncidEth);
// Remove the port from the output list
- ActionBuilder ab = new ActionBuilder();
int index = 2;
- //for (ListIterator<Action> it = oldActionList.listIterator(oldActionList.size()); it.hasPrevious();) {
- // Action action = it.previous();
for (Action action : oldActionList) {
if (action.getAction() instanceof OutputActionCase) {
OutputActionCase opAction = (OutputActionCase) action.getAction();
- if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncidEth))) {
+ if (opAction.getOutputAction().getOutputNodeConnector().equals(ethNodeConnectorUri)) {
actionList.add(action);
- } else if (!opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
- ab.setAction(action.getAction());
- ab.setOrder(index);
- ab.setKey(new ActionKey(index));
- actionList.add(ab.build());
+ } else if (!opAction.getOutputAction().getOutputNodeConnector().equals(localNodeConnectorUri)) {
+ actionList.add(
+ new ActionBuilder()
+ .setAction(action.getAction())
+ .setOrder(index)
+ .setKey(new ActionKey(index))
+ .build());
index++;
}
} else {
actionList.add(action);
}
}
- ApplyActionsBuilder aab = new ApplyActionsBuilder();
- aab.setAction(actionList);
- ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
+ ApplyActions applyActions = new ApplyActionsBuilder().setAction(actionList).build();
+ ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(applyActions).build());
}
if (actionList.size() > 2) {
// Add InstructionBuilder to the Instruction(s)Builder List
+ // TODO This doesn't actually do anything
InstructionsBuilder isb = new InstructionsBuilder();
isb.setInstruction(instructions);
removeFlow = false;
String nodeName = OPENFLOW + dpidLong;
- MatchBuilder matchBuilder = new MatchBuilder();
NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
FlowBuilder flowBuilder = new FlowBuilder();
// Create Match(es) and Set them in the FlowBuilder Object
- flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
+ flowBuilder.setMatch(
+ MatchUtils.createTunnelIDMatch(new MatchBuilder(), new BigInteger(segmentationId)).build());
if (write) {
- // Create the OF Actions and Instructions
- InstructionBuilder ib = new InstructionBuilder();
- InstructionsBuilder isb = new InstructionsBuilder();
-
- // Instructions List Stores Individual Instructions
- List<Instruction> instructions = Lists.newArrayList();
-
// Call the InstructionBuilder Methods Containing Actions
- InstructionUtils.createDropInstructions(ib);
- ib.setOrder(0);
- ib.setKey(new InstructionKey(0));
- instructions.add(ib.build());
-
- // Add InstructionBuilder to the Instruction(s)Builder List
- isb.setInstruction(instructions);
+ Instruction dropInstruction = InstructionUtils.createDropInstructions(new InstructionBuilder())
+ .setOrder(0)
+ .setKey(new InstructionKey(0))
+ .build();
// Add InstructionsBuilder to FlowBuilder
- flowBuilder.setInstructions(isb.build());
+ InstructionUtils.setFlowBuilderInstruction(flowBuilder, dropInstruction);
}
- String flowId = "LocalTableMiss_"+segmentationId;
// Add Flow Attributes
- flowBuilder.setId(new FlowId(flowId));
- FlowKey key = new FlowKey(new FlowId(flowId));
- flowBuilder.setStrict(true);
- flowBuilder.setBarrier(false);
- flowBuilder.setTableId(getTable());
- flowBuilder.setKey(key);
- flowBuilder.setPriority(8192);
- flowBuilder.setFlowName(flowId);
- flowBuilder.setHardTimeout(0);
- flowBuilder.setIdleTimeout(0);
+ String flowName = "LocalTableMiss_" + segmentationId;
+ FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable())
+ .setPriority(8192);
if (write) {
writeFlow(flowBuilder, nodeBuilder);
} else {
String nodeName = OPENFLOW + dpidLong;
- MatchBuilder matchBuilder = new MatchBuilder();
NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
FlowBuilder flowBuilder = new FlowBuilder();
// Create Match(es) and Set them in the FlowBuilder Object
flowBuilder.setMatch(
- MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId)), true).build());
+ MatchUtils.createVlanIdMatch(new MatchBuilder(), new VlanId(Integer.valueOf(segmentationId)),
+ true).build());
if (write) {
- // Create the OF Actions and Instructions
- InstructionBuilder ib = new InstructionBuilder();
- InstructionsBuilder isb = new InstructionsBuilder();
-
- // Instructions List Stores Individual Instructions
- List<Instruction> instructions = Lists.newArrayList();
-
// Call the InstructionBuilder Methods Containing Actions
- InstructionUtils.createDropInstructions(ib);
- ib.setOrder(0);
- ib.setKey(new InstructionKey(0));
- instructions.add(ib.build());
-
- // Add InstructionBuilder to the Instruction(s)Builder List
- isb.setInstruction(instructions);
+ Instruction dropInstruction = InstructionUtils.createDropInstructions(new InstructionBuilder())
+ .setOrder(0)
+ .setKey(new InstructionKey(0))
+ .build();
// Add InstructionsBuilder to FlowBuilder
- flowBuilder.setInstructions(isb.build());
+ InstructionUtils.setFlowBuilderInstruction(flowBuilder, dropInstruction);
}
- String flowId = "LocalTableMiss_"+segmentationId;
// Add Flow Attributes
- flowBuilder.setId(new FlowId(flowId));
- FlowKey key = new FlowKey(new FlowId(flowId));
- flowBuilder.setStrict(true);
- flowBuilder.setBarrier(false);
- flowBuilder.setTableId(getTable());
- flowBuilder.setKey(key);
- flowBuilder.setPriority(8192);
- flowBuilder.setFlowName(flowId);
- flowBuilder.setHardTimeout(0);
- flowBuilder.setIdleTimeout(0);
+ String flowName = "LocalTableMiss_" + segmentationId;
+ FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable())
+ .setPriority(8192);
if (write) {
writeFlow(flowBuilder, nodeBuilder);
} else {
String nodeName = OPENFLOW + dpidLong;
- MatchBuilder matchBuilder = new MatchBuilder();
NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
FlowBuilder flowBuilder = new FlowBuilder();
// Create the OF Match using MatchBuilder
- flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
- flowBuilder.setMatch(MatchUtils.createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
+ MatchBuilder matchBuilder = new MatchBuilder();
+ MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId));
+ MatchUtils.createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null);
+ flowBuilder.setMatch(matchBuilder.build());
- String flowId = "TunnelOut_"+segmentationId+"_"+OFPortOut+"_"+attachedMac;
// Add Flow Attributes
- flowBuilder.setId(new FlowId(flowId));
- FlowKey key = new FlowKey(new FlowId(flowId));
- flowBuilder.setStrict(true);
- flowBuilder.setBarrier(false);
- flowBuilder.setTableId(getTable());
- flowBuilder.setKey(key);
- flowBuilder.setFlowName(flowId);
- flowBuilder.setHardTimeout(0);
- flowBuilder.setIdleTimeout(0);
+ String flowName = "TunnelOut_" + segmentationId + "_" + OFPortOut + "_" + attachedMac;
+ FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable());
if (write) {
- // Instantiate the Builders for the OF Actions and Instructions
- InstructionBuilder ib = new InstructionBuilder();
- InstructionsBuilder isb = new InstructionsBuilder();
-
- // Instructions List Stores Individual Instructions
- List<Instruction> instructions = Lists.newArrayList();
-
// Set the Output Port/Iface
- InstructionUtils.createOutputPortInstructions(ib, dpidLong, OFPortOut);
- ib.setOrder(0);
- ib.setKey(new InstructionKey(1));
- instructions.add(ib.build());
-
- // Add InstructionBuilder to the Instruction(s)Builder List
- isb.setInstruction(instructions);
+ Instruction outputPortInstruction =
+ InstructionUtils.createOutputPortInstructions(new InstructionBuilder(), dpidLong, OFPortOut)
+ .setOrder(0)
+ .setKey(new InstructionKey(1))
+ .build();
// Add InstructionsBuilder to FlowBuilder
- flowBuilder.setInstructions(isb.build());
+ InstructionUtils.setFlowBuilderInstruction(flowBuilder, outputPortInstruction);
writeFlow(flowBuilder, nodeBuilder);
} else {
String nodeName = OPENFLOW + dpidLong;
- MatchBuilder matchBuilder = new MatchBuilder();
NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
FlowBuilder flowBuilder = new FlowBuilder();
// Create the OF Match using MatchBuilder
- flowBuilder.setMatch(
- MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId)), true).build());
- flowBuilder.setMatch(MatchUtils.createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
+ MatchBuilder matchBuilder = new MatchBuilder();
+ MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId)), true);
+ MatchUtils.createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null);
+ flowBuilder.setMatch(matchBuilder.build());
- String flowId = "VlanOut_"+segmentationId+"_"+ethPort+"_"+attachedMac;
// Add Flow Attributes
- flowBuilder.setId(new FlowId(flowId));
- FlowKey key = new FlowKey(new FlowId(flowId));
- flowBuilder.setStrict(true);
- flowBuilder.setBarrier(false);
- flowBuilder.setTableId(getTable());
- flowBuilder.setKey(key);
- flowBuilder.setFlowName(flowId);
- flowBuilder.setHardTimeout(0);
- flowBuilder.setIdleTimeout(0);
+ String flowName = "VlanOut_" + segmentationId + "_" + ethPort + "_" + attachedMac;
+ FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable());
if (write) {
- // Instantiate the Builders for the OF Actions and Instructions
- InstructionBuilder ib = new InstructionBuilder();
- InstructionsBuilder isb = new InstructionsBuilder();
-
// Instructions List Stores Individual Instructions
- List<Instruction> instructions = Lists.newArrayList();
- InstructionUtils.createOutputPortInstructions(ib, dpidLong, ethPort);
- ib.setOrder(0);
- ib.setKey(new InstructionKey(1));
- instructions.add(ib.build());
-
- // Add InstructionBuilder to the Instruction(s)Builder List
- isb.setInstruction(instructions);
+ Instruction outputPortInstruction =
+ InstructionUtils.createOutputPortInstructions(new InstructionBuilder(), dpidLong, ethPort)
+ .setOrder(0)
+ .setKey(new InstructionKey(1))
+ .build();
// Add InstructionsBuilder to FlowBuilder
- flowBuilder.setInstructions(isb.build());
+ InstructionUtils.setFlowBuilderInstruction(flowBuilder, outputPortInstruction);
writeFlow(flowBuilder, nodeBuilder);
} else {
String nodeName = OPENFLOW + dpidLong;
- MatchBuilder matchBuilder = new MatchBuilder();
NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
FlowBuilder flowBuilder = new FlowBuilder();
// Create the OF Match using MatchBuilder
+ MatchBuilder matchBuilder = new MatchBuilder();
// Match TunnelID
- MatchUtils.addNxRegMatch(matchBuilder, new MatchUtils.RegMatch(ClassifierService.REG_FIELD, ClassifierService.REG_VALUE_FROM_LOCAL));
- flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
+ MatchUtils.addNxRegMatch(matchBuilder,
+ new MatchUtils.RegMatch(ClassifierService.REG_FIELD, ClassifierService.REG_VALUE_FROM_LOCAL));
+ MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId));
// Match DMAC
- flowBuilder.setMatch(MatchUtils.createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"),
- new MacAddress("01:00:00:00:00:00")).build());
+ MatchUtils.createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"),
+ new MacAddress("01:00:00:00:00:00"));
+ flowBuilder.setMatch(matchBuilder.build());
- String flowId = "TunnelFloodOut_"+segmentationId;
// Add Flow Attributes
- flowBuilder.setId(new FlowId(flowId));
- FlowKey key = new FlowKey(new FlowId(flowId));
- flowBuilder.setBarrier(true);
- flowBuilder.setTableId(getTable());
- flowBuilder.setKey(key);
- flowBuilder.setPriority(16383); // FIXME: change it back to 16384 once bug 3005 is fixed.
- flowBuilder.setFlowName(flowId);
- flowBuilder.setHardTimeout(0);
- flowBuilder.setIdleTimeout(0);
+ String flowName = "TunnelFloodOut_" + segmentationId;
+ final FlowId flowId = new FlowId(flowName);
+ flowBuilder
+ .setId(flowId)
+ .setBarrier(true)
+ .setTableId(getTable())
+ .setKey(new FlowKey(flowId))
+ .setPriority(16383) // FIXME: change it back to 16384 once bug 3005 is fixed.
+ .setFlowName(flowName)
+ .setHardTimeout(0)
+ .setIdleTimeout(0);
Flow flow = this.getFlow(flowBuilder, nodeBuilder);
// Instantiate the Builders for the OF Actions and Instructions
- InstructionBuilder ib = new InstructionBuilder();
- InstructionsBuilder isb = new InstructionsBuilder();
- List<Instruction> instructions = Lists.newArrayList();
- List<Instruction> existingInstructions = null;
- if (flow != null) {
- Instructions ins = flow.getInstructions();
- if (ins != null) {
- existingInstructions = ins.getInstruction();
- }
- }
+ List<Instruction> existingInstructions = InstructionUtils.extractExistingInstructions(flow);
if (write) {
// Set the Output Port/Iface
- //createOutputGroupInstructions(nodeBuilder, ib, dpidLong, OFPortOut, existingInstructions);
- createOutputPortInstructions(ib, dpidLong, OFPortOut, existingInstructions);
- ib.setOrder(0);
- ib.setKey(new InstructionKey(0));
- instructions.add(ib.build());
-
- // Add InstructionBuilder to the Instruction(s)Builder List
- isb.setInstruction(instructions);
+ Instruction outputPortInstruction =
+ createOutputPortInstructions(new InstructionBuilder(), dpidLong, OFPortOut, existingInstructions)
+ .setOrder(0)
+ .setKey(new InstructionKey(0))
+ .build();
// Add InstructionsBuilder to FlowBuilder
- flowBuilder.setInstructions(isb.build());
+ InstructionUtils.setFlowBuilderInstruction(flowBuilder, outputPortInstruction);
writeFlow(flowBuilder, nodeBuilder);
} else {
+ InstructionBuilder ib = new InstructionBuilder();
/* remove port from action list */
boolean flowRemove = InstructionUtils.removeOutputPortFromInstructions(ib, dpidLong,
OFPortOut, existingInstructions);
removeFlow(flowBuilder, nodeBuilder);
} else {
/* Install instruction with new output port list*/
- ib.setOrder(0);
- ib.setKey(new InstructionKey(0));
- instructions.add(ib.build());
-
- // Add InstructionBuilder to the Instruction(s)Builder List
- isb.setInstruction(instructions);
+ Instruction instruction = ib
+ .setOrder(0)
+ .setKey(new InstructionKey(0))
+ .build();
// Add InstructionsBuilder to FlowBuilder
- flowBuilder.setInstructions(isb.build());
+ InstructionUtils.setFlowBuilderInstruction(flowBuilder, instruction);
writeFlow(flowBuilder, nodeBuilder);
}
}
String nodeName = OPENFLOW + dpidLong;
- MatchBuilder matchBuilder = new MatchBuilder();
NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
FlowBuilder flowBuilder = new FlowBuilder();
// Create the OF Match using MatchBuilder
+ MatchBuilder matchBuilder = new MatchBuilder();
// Match Vlan ID
- flowBuilder.setMatch(
- MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId)), true).build());
+ MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId)), true);
// Match DMAC
- flowBuilder.setMatch(MatchUtils.createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"),
- new MacAddress("01:00:00:00:00:00")).build());
+ MatchUtils.createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"),
+ new MacAddress("01:00:00:00:00:00"));
+ flowBuilder.setMatch(matchBuilder.build());
- String flowId = "VlanFloodOut_"+segmentationId+"_"+ethPort;
// Add Flow Attributes
- flowBuilder.setId(new FlowId(flowId));
- FlowKey key = new FlowKey(new FlowId(flowId));
- flowBuilder.setBarrier(true);
- flowBuilder.setTableId(getTable());
- flowBuilder.setKey(key);
- flowBuilder.setPriority(16384);
- flowBuilder.setFlowName(flowId);
- flowBuilder.setHardTimeout(0);
- flowBuilder.setIdleTimeout(0);
+ String flowName = "VlanFloodOut_" + segmentationId + "_" + ethPort;
+ final FlowId flowId = new FlowId(flowName);
+ flowBuilder
+ .setId(flowId)
+ .setBarrier(true)
+ .setTableId(getTable())
+ .setKey(new FlowKey(flowId))
+ .setPriority(16384)
+ .setFlowName(flowName)
+ .setHardTimeout(0)
+ .setIdleTimeout(0);
//ToDo: Is there something to be done with result of the call to getFlow?
-
Flow flow = this.getFlow(flowBuilder, nodeBuilder);
- // Instantiate the Builders for the OF Actions and Instructions
- InstructionBuilder ib = new InstructionBuilder();
- InstructionsBuilder isb = new InstructionsBuilder();
- List<Instruction> instructions = Lists.newArrayList();
if (write) {
// Set the Output Port/Iface
- InstructionUtils.createOutputPortInstructions(ib, dpidLong, ethPort);
- ib.setOrder(0);
- ib.setKey(new InstructionKey(0));
- instructions.add(ib.build());
-
- // Add InstructionBuilder to the Instruction(s)Builder List
- isb.setInstruction(instructions);
+ Instruction outputPortInstruction =
+ InstructionUtils.createOutputPortInstructions(new InstructionBuilder(), dpidLong, ethPort)
+ .setOrder(0)
+ .setKey(new InstructionKey(0))
+ .build();
// Add InstructionsBuilder to FlowBuilder
- flowBuilder.setInstructions(isb.build());
+ InstructionUtils.setFlowBuilderInstruction(flowBuilder, outputPortInstruction);
writeFlow(flowBuilder, nodeBuilder);
} else {
String nodeName = OPENFLOW + dpidLong;
- MatchBuilder matchBuilder = new MatchBuilder();
NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
FlowBuilder flowBuilder = new FlowBuilder();
// Create Match(es) and Set them in the FlowBuilder Object
- flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
+ flowBuilder.setMatch(
+ MatchUtils.createTunnelIDMatch(new MatchBuilder(), new BigInteger(segmentationId)).build());
if (write) {
- // Create the OF Actions and Instructions
- InstructionsBuilder isb = new InstructionsBuilder();
-
- // Instructions List Stores Individual Instructions
- List<Instruction> instructions = Lists.newArrayList();
-
// Call the InstructionBuilder Methods Containing Actions
- InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
- ib.setOrder(0);
- ib.setKey(new InstructionKey(0));
- instructions.add(ib.build());
-
- // Add InstructionBuilder to the Instruction(s)Builder List
- isb.setInstruction(instructions);
+ Instruction mutablePipelineInstruction = getMutablePipelineInstructionBuilder()
+ .setOrder(0)
+ .setKey(new InstructionKey(0))
+ .build();
// Add InstructionsBuilder to FlowBuilder
- flowBuilder.setInstructions(isb.build());
+ InstructionUtils.setFlowBuilderInstruction(flowBuilder, mutablePipelineInstruction);
}
- String flowId = "TunnelMiss_"+segmentationId;
// Add Flow Attributes
- flowBuilder.setId(new FlowId(flowId));
- FlowKey key = new FlowKey(new FlowId(flowId));
- flowBuilder.setStrict(true);
- flowBuilder.setBarrier(false);
- flowBuilder.setTableId(getTable());
- flowBuilder.setKey(key);
- flowBuilder.setPriority(8192);
- flowBuilder.setFlowName(flowId);
- flowBuilder.setHardTimeout(0);
- flowBuilder.setIdleTimeout(0);
+ String flowName = "TunnelMiss_" + segmentationId;
+ FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable())
+ .setPriority(8192);
if (write) {
writeFlow(flowBuilder, nodeBuilder);
} else {
String nodeName = OPENFLOW + dpidLong;
- MatchBuilder matchBuilder = new MatchBuilder();
NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
FlowBuilder flowBuilder = new FlowBuilder();
// Create Match(es) and Set them in the FlowBuilder Object
flowBuilder.setMatch(
- MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId)), true).build());
+ MatchUtils.createVlanIdMatch(new MatchBuilder(), new VlanId(Integer.valueOf(segmentationId)),
+ true).build());
if (write) {
- // Create the OF Actions and Instructions
- InstructionBuilder ib = new InstructionBuilder();
- InstructionsBuilder isb = new InstructionsBuilder();
-
- // Instructions List Stores Individual Instructions
- List<Instruction> instructions = Lists.newArrayList();
-
// Set the Output Port/Iface
- InstructionUtils.createOutputPortInstructions(ib, dpidLong, ethPort);
- ib.setOrder(0);
- ib.setKey(new InstructionKey(1));
- instructions.add(ib.build());
-
- // Add InstructionBuilder to the Instruction(s)Builder List
- isb.setInstruction(instructions);
+ Instruction outputPortInstruction =
+ InstructionUtils.createOutputPortInstructions(new InstructionBuilder(), dpidLong, ethPort)
+ .setOrder(0)
+ .setKey(new InstructionKey(1))
+ .build();
// Add InstructionsBuilder to FlowBuilder
- flowBuilder.setInstructions(isb.build());
+ InstructionUtils.setFlowBuilderInstruction(flowBuilder, outputPortInstruction);
}
- String flowId = "VlanMiss_"+segmentationId;
// Add Flow Attributes
- flowBuilder.setId(new FlowId(flowId));
- FlowKey key = new FlowKey(new FlowId(flowId));
- flowBuilder.setStrict(true);
- flowBuilder.setBarrier(false);
- flowBuilder.setTableId(getTable());
- flowBuilder.setKey(key);
- flowBuilder.setPriority(8192);
- flowBuilder.setFlowName(flowId);
- flowBuilder.setHardTimeout(0);
- flowBuilder.setIdleTimeout(0);
+ String flowName = "VlanMiss_" + segmentationId;
+ FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable())
+ .setPriority(8192);
if (write) {
writeFlow(flowBuilder, nodeBuilder);
} else {
NodeConnectorId ncid = new NodeConnectorId(OPENFLOW + dpidLong + ":" + port);
LOG.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
- List<Action> actionList = Lists.newArrayList();
+ List<Action> actionList = new ArrayList<>();
ActionBuilder ab = new ActionBuilder();
List<Action> existingActions;
verify(commitFuture, times(1)).get();
}
*/
+ /**
+ * Test method {@link EgressAclService#programPortSecurityGroup(java.lang.Long, java.lang.String,
+ * java.lang.String, long, org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup,
+ * java.lang.String, boolean)} when portSecurityRule is incomplete
+ */
+ @Test
+ public void testProgramPortSecurityGroupWithIncompleteRule() throws Exception {
+ NeutronSecurityRule portSecurityRule1 = mock(NeutronSecurityRule.class);
+ when(portSecurityRule1.getSecurityRuleEthertype()).thenReturn("IPv4");
+ when(portSecurityRule1.getSecurityRuleDirection()).thenReturn("not_egress"); // other direction
+
+ NeutronSecurityRule portSecurityRule2 = mock(NeutronSecurityRule.class);
+ when(portSecurityRule2.getSecurityRuleEthertype()).thenReturn(null);
+ when(portSecurityRule2.getSecurityRuleDirection()).thenReturn("egress");
+
+ NeutronSecurityRule portSecurityRule3 = mock(NeutronSecurityRule.class);
+ when(portSecurityRule3.getSecurityRuleEthertype()).thenReturn("IPv4");
+ when(portSecurityRule3.getSecurityRuleDirection()).thenReturn(null);
+
+ NeutronSecurityRule portSecurityRule4 = mock(NeutronSecurityRule.class);
+ when(portSecurityRule4.getSecurityRuleEthertype()).thenReturn(null);
+ when(portSecurityRule4.getSecurityRuleDirection()).thenReturn(null);
+
+ List<NeutronSecurityRule> portSecurityList = new ArrayList<>();
+ portSecurityList.add(null);
+ portSecurityList.add(portSecurityRule1);
+ portSecurityList.add(portSecurityRule2);
+ portSecurityList.add(portSecurityRule3);
+ portSecurityList.add(portSecurityRule4);
+
+ NeutronSecurityGroup localSecurityGroup = mock(NeutronSecurityGroup.class);
+ when(localSecurityGroup.getSecurityRules()).thenReturn(portSecurityList);
+
+ egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT,
+ localSecurityGroup, PORT_UUID, true);
+ }
+
/**
* Test method {@link EgressAclService#egressACLDefaultTcpDrop(Long, String, String, int, boolean)}
*/
verify(commitFuture, times(1)).get();
}
*/
+ /**
+ * Test method {@link EgressAclService#programPortSecurityGroup(java.lang.Long, java.lang.String,
+ * java.lang.String, long, org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup,
+ * java.lang.String, boolean)} when portSecurityRule is incomplete
+ */
+ @Test
+ public void testProgramPortSecurityGroupWithIncompleteRule() throws Exception {
+ NeutronSecurityRule portSecurityRule1 = mock(NeutronSecurityRule.class);
+ when(portSecurityRule1.getSecurityRuleEthertype()).thenReturn("IPv4");
+ when(portSecurityRule1.getSecurityRuleDirection()).thenReturn("not_ingress"); // other direction
+
+ NeutronSecurityRule portSecurityRule2 = mock(NeutronSecurityRule.class);
+ when(portSecurityRule2.getSecurityRuleEthertype()).thenReturn(null);
+ when(portSecurityRule2.getSecurityRuleDirection()).thenReturn("ingress");
+
+ NeutronSecurityRule portSecurityRule3 = mock(NeutronSecurityRule.class);
+ when(portSecurityRule3.getSecurityRuleEthertype()).thenReturn("IPv4");
+ when(portSecurityRule3.getSecurityRuleDirection()).thenReturn(null);
+
+ NeutronSecurityRule portSecurityRule4 = mock(NeutronSecurityRule.class);
+ when(portSecurityRule4.getSecurityRuleEthertype()).thenReturn(null);
+ when(portSecurityRule4.getSecurityRuleDirection()).thenReturn(null);
+
+ List<NeutronSecurityRule> portSecurityList = new ArrayList<>();
+ portSecurityList.add(null);
+ portSecurityList.add(portSecurityRule1);
+ portSecurityList.add(portSecurityRule2);
+ portSecurityList.add(portSecurityRule3);
+ portSecurityList.add(portSecurityRule4);
+
+ NeutronSecurityGroup localSecurityGroup = mock(NeutronSecurityGroup.class);
+ when(localSecurityGroup.getSecurityRules()).thenReturn(portSecurityList);
+
+ ingressAclServiceSpy.programPortSecurityGroup(
+ Long.valueOf(1554), "2", MAC_ADDRESS, 124, localSecurityGroup, PORT_UUID, false);
+ }
+
/**
* Test IPv4 add test case.
*/
<Export-Package>
org.opendaylight.yang.gen.v1.*,
org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.acl.rev150105,
- org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.acl.rev150105.*,
org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105,
- org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.*,
org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev150105,
- org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev150105.*
</Export-Package>
</instructions>
</configuration>
description "Initial revision of netvirt extensions to ietf-acl model";
}
- // TODO: Add choice for Neutron and add fields there instead of at the root of matches
//augment "/ietf-acl:access-lists/ietf-acl:access-list/ietf-acl:access-list-entries/ietf-acl:access-list-entry/ietf-acl:matches" {
augment "/ietf-acl:access-lists/ietf-acl:acl/ietf-acl:access-list-entries/ietf-acl:ace/ietf-acl:matches" {
description "Neutron network uuid";
}
}
- // TODO: Add choice for Neutron and add fields there instead of at the root of matches
augment "/ietf-acl:access-lists/ietf-acl:acl/ietf-acl:access-list-entries/ietf-acl:ace/ietf-acl:actions" {
- description "Redirect traffic to SFC identified by SFC Path ID";
+ description "Redirect traffic to SFC identified by either SFC, SFP or RSP";
ext:augment-identifier "redirect-to-sfc";
- leaf redirect-sfc {
+ leaf sfc-name {
+ type string;
+ }
+ leaf sfp-name {
+ type string;
+ }
+ leaf rsp-name {
type string;
}
}
<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>org.opendaylight.sfc</groupId>
- <artifactId>features-sfcofl2</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>
<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.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.openflowplugin/features-openflowplugin/${openflowplugin.version}/xml/features</repository>
- <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin-extension/${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.sfc/features-sfcofl2/${sfc.version}/xml/features</repository>
- <repository>mvn:org.opendaylight.yangtools/features-yangtools/${yangtools.version}/xml/features</repository>
+ <repository>mvn:org.opendaylight.controller/features-mdsal/{{VERSION}}/xml/features</repository>
+ <repository>mvn:org.opendaylight.dlux/features-dlux/{{VERSION}}/xml/features</repository>
+ <repository>mvn:org.opendaylight.mdsal.model/features-mdsal-model/{{VERSION}}/xml/features</repository>
+ <repository>mvn:org.opendaylight.netconf/features-restconf/{{VERSION}}/xml/features</repository>
+ <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin/{{VERSION}}/xml/features</repository>
+ <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin-extension/{{VERSION}}/xml/features</repository>
+ <repository>mvn:org.opendaylight.ovsdb/features-ovsdb/{{VERSION}}/xml/features</repository>
+ <repository>mvn:org.opendaylight.ovsdb/southbound-features/{{VERSION}}/xml/features</repository>
+ <repository>mvn:org.opendaylight.sfc/features-sfc/{{VERSION}}/xml/features</repository>
+ <repository>mvn:org.opendaylight.yangtools/features-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>
+ <bundle>mvn:org.opendaylight.ovsdb/openstack.net-virt-sfc-api/{{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='${sfc.version}'>odl-sfc-provider</feature>
<feature version='${sfc.version}'>odl-sfcofl2</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>
+ <bundle>mvn:org.opendaylight.ovsdb/utils.mdsal-utils/{{VERSION}}</bundle>
+ <bundle>mvn:org.opendaylight.ovsdb/utils.servicehelper/{{VERSION}}</bundle>
+ <bundle>mvn:org.opendaylight.ovsdb/openstack.net-virt-sfc-impl/{{VERSION}}</bundle>
+ <configfile finalname="${configfile.directory}/openstack.net-virt-sfc.xml">mvn:org.opendaylight.ovsdb/openstack.net-virt-sfc-impl/{{VERSION}}/xml/config</configfile>
</feature>
<feature name='odl-ovsdb-sfc-rest' version='${project.version}' description='OpenDaylight :: ovsdb-sfc :: REST'>
<feature version="${project.version}">odl-ovsdb-sfc</feature>
xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
<repository>mvn:org.opendaylight.ovsdb/openstack.net-virt-sfc-features/1.2.1-SNAPSHOT/xml/features</repository>
<feature name='odl-ovsdb-sfc-test' version='${project.version}' description='OpenDaylight :: ovsdb-sfc-test'>
- <bundle>mvn:org.opendaylight.ovsdb/utils.mdsal-utils/${project.version}</bundle>
- <bundle>mvn:org.opendaylight.ovsdb/utils.southbound-utils/${project.version}</bundle>
+ <bundle>mvn:org.opendaylight.ovsdb/utils.mdsal-utils/{{VERSION}}</bundle>
+ <bundle>mvn:org.opendaylight.ovsdb/utils.southbound-utils/{{VERSION}}</bundle>
<feature version='${project.version}'>odl-ovsdb-sfc-ui</feature>
</feature>
</features>
<version>${sonar-jacoco-listeners.version}</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.mdsal.model</groupId>
+ <artifactId>iana-if-type-2014-05-08</artifactId>
+ <version>2014.05.08.8-SNAPSHOT</version>
+ </dependency>
</dependencies>
<build>
void programEgressClassifier1(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
int tunnelOfPort, int tunnelId, short gotoTableId, boolean write);
- void programEgressClassifier2(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
- int tunnelOfPort, int tunnelId, boolean write);
+ void programEgressClassifier(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
+ long sfOfPort, int tunnelId, boolean write);
+
+ void programEgressClassifierBypass(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
+ long sfOfPort, int tunnelId, boolean write);
void program_sfEgress(long dataPathId, int dstPort, boolean write);
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.ServiceFunctions;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.functions.ServiceFunction;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.functions.ServiceFunctionKey;
+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.cisco.params.xml.ns.yang.sfc.sfp.rev140701.ServiceFunctionPaths;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPath;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sl.rev140701.data.plane.locator.locator.type.Ip;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.Classifiers;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
.child(ServiceFunction.class, new ServiceFunctionKey(SfName.getDefaultInstance(sfName))).build();
}
+ public RenderedServicePath getRsp(String rspName) {
+ return mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, getRspId(rspName));
+ }
+
public RenderedServicePath getRspforSfp(String sfpName) {
RenderedServicePath rspFound = null;
RenderedServicePaths rsps = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, this.getRspsId());
return sfpFound;
}
- public IpAddress getSfIp(String sfname) {
+ public IpAddress getSfIpAddress(String sfname) {
ServiceFunction serviceFunction =
SfcProviderServiceFunctionAPI.readServiceFunction(SfName.getDefaultInstance(sfname));
return null;
}
- return getSfIp(serviceFunction);
+ return getSfIpAddress(serviceFunction);
}
- public IpAddress getSfIp(ServiceFunction serviceFunction) {
+ public IpAddress getSfIpAddress(ServiceFunction serviceFunction) {
if (serviceFunction == null) {
LOG.info("getSfIp: Servicefunction is null");
return null;
return ipLocator.getIp();
}
+ public PortNumber getSfPort(ServiceFunction serviceFunction) {
+ if (serviceFunction == null) {
+ LOG.info("getSfIp: Servicefunction is null");
+ return null;
+ }
+
+ Ip ipLocator = (Ip) serviceFunction.getSfDataPlaneLocator().get(0).getLocatorType();
+ return ipLocator.getPort();
+ }
+
+ public Ip getSfIp(ServiceFunction serviceFunction) {
+ if (serviceFunction == null) {
+ LOG.info("getSfIp: Servicefunction is null");
+ return null;
+ }
+
+ return (Ip)serviceFunction.getSfDataPlaneLocator().get(0).getLocatorType();
+ }
+
public String getSfDplName(ServiceFunction serviceFunction) {
String sfDplName = null;
if (serviceFunction == null) {
sfDplName = serviceFunction.getSfDataPlaneLocator().get(0).getName().getValue();
return sfDplName;
}
+
+ public Ip getSffIp(ServiceFunctionForwarder serviceFunctionForwarder) {
+ if (serviceFunctionForwarder == null) {
+ LOG.info("getSfIp: ServicefunctionForwarder is null");
+ return null;
+ }
+
+ return (Ip)serviceFunctionForwarder.getSffDataPlaneLocator().get(0).getDataPlaneLocator().getLocatorType();
+ }
}
return;
}
- RedirectToSfc sfcRedirect = entry.getActions().getAugmentation(RedirectToSfc.class);
- LOG.debug("Processing ACL entry = {} sfcRedirect = {}", entry.getRuleName(), sfcRedirect);
- if (sfcRedirect == null) {
- LOG.warn("processAClEntry: sfcRedirect is null");
- return;
- }
-
- String sfcName = sfcRedirect.getRedirectSfc();
- LOG.debug("Processing Redirect to SFC = {}", sfcRedirect.getRedirectSfc());
- ServiceFunctionPath sfp = getSfp(sfcName);
- if (sfp == null || sfp.getName() == null) {
- LOG.warn("There is no configured SFP with sfcName = {}; so skip installing the ACL entry!!", sfcName);
- return;
- }
-
- LOG.debug("Processing Redirect to SFC = {}, SFP = {}", sfcRedirect.getRedirectSfc(), sfp);
- // If RSP doesn't exist, create an RSP.
- String sfpName = sfp.getName().getValue();
- RenderedServicePath rsp = getRspforSfp(sfpName);
- String rspName = sfp.getName().getValue() + "_rsp";
+ RenderedServicePath rsp = getRenderedServicePath(entry);
if (rsp == null) {
- LOG.info("No configured RSP corresponding to SFP = {}, Creating new RSP = {}", sfpName, rspName);
- CreateRenderedPathInput rspInput = new CreateRenderedPathInputBuilder()
- .setParentServiceFunctionPath(sfpName)
- .setName(rspName)
- .setSymmetric(sfp.isSymmetric())
- .build();
- rsp = SfcProviderRenderedPathAPI.createRenderedServicePathAndState(sfp, rspInput);
- if (rsp == null) {
- LOG.warn("failed to add RSP");
- return;
- }
-
- // If SFP is symmetric, create RSP in the reverse direction.
- if (sfp.isSymmetric()) {
- LOG.info("SFP = {} is symmetric, installing RSP in the reverse direction!!", sfpName);
- String rspNameRev = rspName + "-Reverse";
- RenderedServicePath rspReverse = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
- this.getRspId(rspNameRev));
- if (rspReverse == null) {
- rspReverse = SfcProviderRenderedPathAPI.createSymmetricRenderedServicePathAndState(rsp);
- if (rspReverse == null) {
- LOG.warn("failed to add reverse RSP");
- return;
- }
- }
- }
+ LOG.warn("Failed to get renderedServicePatch for entry: {}", entry);
+ return;
}
LOG.info("processAclEntry: RSP: {}", rsp);
List<RenderedServicePathHop> pathHopList = rsp.getRenderedServicePathHop();
if (pathHopList.isEmpty()) {
- LOG.warn("Service Path = {} has empty hops!!", sfpName);
+ LOG.warn("Service Path = {} has empty hops!!", rsp.getName());
return;
}
// Find the first Hop within an RSP.
// The classifier flow needs to send all matched traffic to this first hop SFF.
RenderedServicePathFirstHop firstRspHop = SfcProviderRenderedPathAPI
- .readRenderedServicePathFirstHop(new RspName(rspName));
+ .readRenderedServicePathFirstHop(new RspName(rsp.getName()));
LOG.debug("First Hop IPAddress = {}, Port = {}", firstRspHop.getIp().getIpv4Address().getValue(),
- firstRspHop.getPort().getValue().intValue());
+ firstRspHop.getPort().getValue());
NshUtils nshHeader = new NshUtils();
// C1 is the normal overlay dest ip and c2 is the vnid
}
}
+ private RenderedServicePath getRenderedServicePath (Ace entry) {
+ RenderedServicePath rsp = null;
+ RedirectToSfc sfcRedirect = entry.getActions().getAugmentation(RedirectToSfc.class);
+ LOG.debug("Processing ACL entry = {} sfcRedirect = {}", entry.getRuleName(), sfcRedirect);
+ if (sfcRedirect == null) {
+ LOG.warn("processAClEntry: sfcRedirect is null");
+ return null;
+ }
+
+ if (sfcRedirect.getRspName() != null) {
+ rsp = getRenderedServicePathFromRsp(sfcRedirect.getRspName());
+ } else if (sfcRedirect.getSfpName() != null) {
+ LOG.warn("getRenderedServicePath: sfp not handled yet");
+ } else {
+ rsp = getRenderedServicePathFromSfc(entry);
+ }
+ LOG.info("getRenderedServicePath: rsp: {}", rsp);
+ return rsp;
+ }
+
+ private RenderedServicePath getRenderedServicePathFromRsp(String rspName) {
+ return null;//getRsp(rspName);
+ }
+
+ private RenderedServicePath getRenderedServicePathFromSfc (Ace entry) {
+ RedirectToSfc sfcRedirect = entry.getActions().getAugmentation(RedirectToSfc.class);
+ LOG.debug("Processing ACL entry = {} sfcRedirect = {}", entry.getRuleName(), sfcRedirect);
+ if (sfcRedirect == null) {
+ LOG.warn("processAClEntry: sfcRedirect is null");
+ return null;
+ }
+
+ String sfcName = sfcRedirect.getSfcName();
+ ServiceFunctionPath sfp = getSfp(sfcName);
+ if (sfp == null || sfp.getName() == null) {
+ LOG.warn("There is no configured SFP with sfcName = {}; so skip installing the ACL entry!!", sfcName);
+ return null;
+ }
+
+ LOG.debug("Processing Redirect to SFC = {}, SFP = {}", sfcName, sfp);
+ // If RSP doesn't exist, create an RSP.
+ String sfpName = sfp.getName().getValue();
+ RenderedServicePath rsp = getRspforSfp(sfpName);
+ String rspName = sfp.getName().getValue() + "_rsp";
+ if (rsp == null) {
+ LOG.info("No configured RSP corresponding to SFP = {}, Creating new RSP = {}", sfpName, rspName);
+ CreateRenderedPathInput rspInput = new CreateRenderedPathInputBuilder()
+ .setParentServiceFunctionPath(sfpName)
+ .setName(rspName)
+ .setSymmetric(sfp.isSymmetric())
+ .build();
+ rsp = SfcProviderRenderedPathAPI.createRenderedServicePathAndState(sfp, rspInput);
+ if (rsp == null) {
+ LOG.warn("failed to add RSP");
+ return null;
+ }
+
+ // If SFP is symmetric, create RSP in the reverse direction.
+ if (sfp.isSymmetric()) {
+ LOG.info("SFP = {} is symmetric, installing RSP in the reverse direction!!", sfpName);
+ String rspNameRev = rspName + "-Reverse";
+ RenderedServicePath rspReverse = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
+ getRspId(rspNameRev));
+ if (rspReverse == null) {
+ rspReverse = SfcProviderRenderedPathAPI.createSymmetricRenderedServicePathAndState(rsp);
+ if (rspReverse == null) {
+ LOG.warn("failed to add reverse RSP");
+ return null;
+ }
+ }
+ }
+ }
+ return rsp;
+ }
+
private void handleLocalEgressPort(long dataPathId, String s, long localOfPort, short writeTable,
short gotoTable, boolean write) {
}
@Override
- public void programEgressClassifier2(long dataPathId, long vxGpeOfPort, long nsp, short nsi, int tunnelOfPort, int tunnelId, boolean write) {
+ public void programEgressClassifier(long dataPathId, long vxGpeOfPort, long nsp, short nsi, long sfOfPort, int tunnelId, boolean write) {
+
+ }
+
+ @Override
+ public void programEgressClassifierBypass(long dataPathId, long vxGpeOfPort, long nsp, short nsi, long sfOfPort, int tunnelId, boolean write) {
}
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.OvsdbTables;
import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
import org.opendaylight.ovsdb.openstack.netvirt.sfc.INetvirtSfcOF13Provider;
import org.opendaylight.ovsdb.openstack.netvirt.sfc.ISfcClassifierService;
import org.opendaylight.ovsdb.openstack.netvirt.sfc.NshUtils;
import org.opendaylight.ovsdb.openstack.netvirt.sfc.SfcUtils;
-import org.opendaylight.ovsdb.openstack.netvirt.sfc.workaround.services.SfcClassifierService;
import org.opendaylight.ovsdb.southbound.SouthboundConstants;
import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
import org.opendaylight.sfc.provider.api.SfcProviderRenderedPathAPI;
+import org.opendaylight.sfc.provider.api.SfcProviderServiceForwarderAPI;
import org.opendaylight.sfc.provider.api.SfcProviderServiceFunctionAPI;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sl.rev140701.data.plane.locator.locator.type.Ip;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.CreateRenderedPathInput;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.CreateRenderedPathInputBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.path.first.hop.info.RenderedServicePathFirstHop;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePath;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.rendered.service.path.RenderedServicePathHop;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.functions.ServiceFunction;
+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.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPath;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.Acl;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.Ace;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.bridges.Bridge;
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.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
private static final String VXGPE = "vxgpe";
private static final String TUNNEL_DST = "192.168.120.31";
private static final String TUNNEL_VNID = "10";
+ public static final String TUNNEL_ENDPOINT_KEY = "local_ip";
public NetvirtSfcWorkaroundOF13Provider(final DataBroker dataBroker, MdsalUtils mdsalUtils, SfcUtils sfcUtils) {
Preconditions.checkNotNull(dataBroker, "Input dataBroker cannot be NULL!");
handleRenderedServicePath(rsp, entry);
}
- private void handleRenderedServicePath(RenderedServicePath rsp, Ace entry) {
+ private void handleRenderedServicePathOld(RenderedServicePath rsp, Ace entry) {
LOG.info("handleRenderedServicePath: RSP: {}", rsp);
Matches matches = entry.getMatches();
LOG.info("handleRenderedServicePath: firstRspHop: {}", firstRspHop);
LOG.debug("handleRenderedServicePath: First Hop IPAddress = {}, Port = {}",
firstRspHop.getIp().getIpv4Address().getValue(),
- firstRspHop.getPort().getValue().intValue());
+ firstRspHop.getPort().getValue());
NshUtils nshHeader = new NshUtils();
nshHeader.setNshMetaC1(NshUtils.convertIpAddressToLong(new Ipv4Address(TUNNEL_DST)));
nshHeader.setNshNsi(firstHop.getServiceIndex());
// workaround: bypass sff and got directly to sf
//nshHeader.setNshTunIpDst(firstRspHop.getIp().getIpv4Address());
- IpAddress sfIpAddress = sfcUtils.getSfIp(serviceFunction);
+ IpAddress sfIpAddress = sfcUtils.getSfIpAddress(serviceFunction);
String sfDplName = sfcUtils.getSfDplName(serviceFunction);
//sfcUtils.getSfIp(firstHop.getServiceFunctionName().getValue());
nshHeader.setNshTunIpDst(sfIpAddress.getIpv4Address());
nshHeader, vxGpeOfPort, true);
sfcClassifierService.program_sfEgress(dataPathId, GPE_PORT, true);
- //not needed if ip route and arp can be added to stack
long sfOfPort = getSfPort(bridgeNode, sfDplName);
String sfMac = getMacFromExternalIds(bridgeNode, sfDplName);
}
short lastServiceindex = (short)((lastHop.getServiceIndex()).intValue() - 1);
- sfcClassifierService.programEgressClassifier1(dataPathId, vxGpeOfPort, rsp.getPathId(),
- lastServiceindex, (int)sfOfPort, 0, (short)0, true);
- sfcClassifierService.programEgressClassifier2(dataPathId, vxGpeOfPort, rsp.getPathId(),
- lastServiceindex, (int)sfOfPort, 0, true);
+ sfcClassifierService.programEgressClassifier(dataPathId, vxGpeOfPort, rsp.getPathId(),
+ lastServiceindex, sfOfPort, 0, true);
+ sfcClassifierService.programEgressClassifierBypass(dataPathId, vxGpeOfPort, rsp.getPathId(),
+ lastServiceindex, sfOfPort, 0, true);
sfcClassifierService.programSfcTable(dataPathId, vxGpeOfPort, SFC_TABLE, true);
}
}
+ private void handleRenderedServicePath(RenderedServicePath rsp, Ace entry) {
+ LOG.info("handleRenderedServicePath: RSP: {}", rsp);
+
+ Matches matches = entry.getMatches();
+ if (matches == null) {
+ LOG.warn("processAclEntry: matches not found");
+ return;
+ }
+
+ List<RenderedServicePathHop> pathHopList = rsp.getRenderedServicePathHop();
+ if (pathHopList.isEmpty()) {
+ LOG.warn("handleRenderedServicePath: RSP {} has empty hops!!", rsp.getName());
+ return;
+ }
+ LOG.info("handleRenderedServicePath: pathHopList: {}", pathHopList);
+
+ RenderedServicePathFirstHop firstRspHop = SfcProviderRenderedPathAPI
+ .readRenderedServicePathFirstHop(rsp.getName());
+ LOG.info("handleRenderedServicePath: firstRspHop: {}", firstRspHop);
+
+ RenderedServicePathHop firstHop = pathHopList.get(0);
+ RenderedServicePathHop lastHop = pathHopList.get(pathHopList.size()-1);
+
+ final List<Node> bridgeNodes = nodeCacheManager.getBridgeNodes();
+ if (bridgeNodes == null || bridgeNodes.isEmpty()) {
+ LOG.warn("handleRenderedServicePath: There are no bridges to process");
+ return;
+ }
+ for (RenderedServicePathHop hop : pathHopList) {
+ for (Node bridgeNode : bridgeNodes) {
+ // ignore bridges other than br-int
+ OvsdbBridgeAugmentation ovsdbBridgeAugmentation = southbound.getBridge(bridgeNode, "br-int");
+ if (ovsdbBridgeAugmentation == null) {
+ continue;
+ }
+ long vxGpeOfPort = getOFPort(bridgeNode, VXGPE);
+ if (vxGpeOfPort == 0L) {
+ LOG.warn("programAclEntry: Could not identify gpe vtep {} -> OF ({}) on {}",
+ VXGPE, vxGpeOfPort, bridgeNode);
+ continue;
+ }
+ long dataPathId = southbound.getDataPathId(bridgeNode);
+ if (dataPathId == 0L) {
+ LOG.warn("programAclEntry: Could not identify datapathId on {}", bridgeNode);
+ continue;
+ }
+
+ ServiceFunction serviceFunction =
+ SfcProviderServiceFunctionAPI.readServiceFunction(firstHop.getServiceFunctionName());
+ if (serviceFunction == null) {
+ LOG.warn("programAclEntry: Could not identify ServiceFunction {} on {}",
+ firstHop.getServiceFunctionName().getValue(), bridgeNode);
+ continue;
+ }
+ ServiceFunctionForwarder serviceFunctionForwarder =
+ SfcProviderServiceForwarderAPI
+ .readServiceFunctionForwarder(hop.getServiceFunctionForwarder());
+ if (serviceFunctionForwarder == null) {
+ LOG.warn("programAclEntry: Could not identify ServiceFunctionForwarder {} on {}",
+ firstHop.getServiceFunctionName().getValue(), bridgeNode);
+ continue;
+ }
+
+ handleSf(bridgeNode, serviceFunction);
+ handleSff(bridgeNode, serviceFunctionForwarder, serviceFunction, hop, firstHop, lastHop,
+ entry.getRuleName(), matches, vxGpeOfPort, rsp);
+ if (firstHop == lastHop) {
+ handleSff(bridgeNode, serviceFunctionForwarder, serviceFunction, hop, null, lastHop,
+ entry.getRuleName(), matches, vxGpeOfPort, rsp);
+ }
+ }
+ }
+ }
+
+ private void handleSff(Node bridgeNode, ServiceFunctionForwarder serviceFunctionForwarder,
+ ServiceFunction serviceFunction,
+ RenderedServicePathHop hop,
+ RenderedServicePathHop firstHop,
+ RenderedServicePathHop lastHop,
+ String ruleName, Matches matches,
+ long vxGpeOfPort, RenderedServicePath rsp) {
+ long dataPathId = southbound.getDataPathId(bridgeNode);
+
+ if (hop == firstHop) {
+ LOG.info("handleSff: first hop processing {} - {}",
+ bridgeNode.getNodeId(), serviceFunctionForwarder.getName());
+ NshUtils nshHeader = new NshUtils();
+ nshHeader.setNshNsp(rsp.getPathId());
+ nshHeader.setNshNsi(firstHop.getServiceIndex());
+ if (isSffOnBridge(bridgeNode, serviceFunctionForwarder)) {
+ LOG.info("handleSff: sff and bridge are the same: {} - {}, skipping first sff",
+ bridgeNode.getNodeId(), serviceFunctionForwarder.getName());
+ Ip ip = sfcUtils.getSfIp(serviceFunction);
+ nshHeader.setNshTunIpDst(ip.getIp().getIpv4Address());
+ nshHeader.setNshTunUdpPort(ip.getPort());
+ } else {
+ LOG.info("handleSff: sff and bridge are not the same: {} - {}, sending to first sff",
+ bridgeNode.getNodeId(), serviceFunctionForwarder.getName());
+ Ip ip = sfcUtils.getSffIp(serviceFunctionForwarder);
+ nshHeader.setNshTunIpDst(ip.getIp().getIpv4Address());
+ nshHeader.setNshTunUdpPort(ip.getPort());
+ }
+ sfcClassifierService.programIngressClassifier(dataPathId, ruleName, matches,
+ nshHeader, vxGpeOfPort, true);
+ } else if (hop == lastHop) {
+ LOG.info("handleSff: last hop processing {} - {}",
+ bridgeNode.getNodeId(), serviceFunctionForwarder.getName());
+ short lastServiceindex = (short)((lastHop.getServiceIndex()).intValue() - 1);
+ String sfDplName = sfcUtils.getSfDplName(serviceFunction);
+ long sfOfPort = getSfPort(bridgeNode, sfDplName);
+ sfcClassifierService.programEgressClassifier(dataPathId, vxGpeOfPort, rsp.getPathId(),
+ lastServiceindex, sfOfPort, 0, true);
+ sfcClassifierService.programEgressClassifierBypass(dataPathId, vxGpeOfPort, rsp.getPathId(),
+ lastServiceindex, sfOfPort, 0, true);
+ } else {
+ // add typical sff flows
+ }
+
+ sfcClassifierService.programSfcTable(dataPathId, vxGpeOfPort, SFC_TABLE, true);
+ }
+
+ void handleSf(Node bridgeNode, ServiceFunction serviceFunction) {
+ if (isSfOnBridge(bridgeNode, serviceFunction)) {
+ LOG.info("handleSf: sf and bridge are on the same node: {} - {}, adding workaround and arp",
+ bridgeNode.getNodeId(), serviceFunction.getName());
+ long dataPathId = southbound.getDataPathId(bridgeNode);
+ Ip ip = sfcUtils.getSfIp(serviceFunction);
+ String sfIpAddr = String.valueOf(ip.getIp().getValue());
+ int sfIpPort = ip.getPort().getValue(); //GPE_PORT
+ String sfDplName = sfcUtils.getSfDplName(serviceFunction);
+ long sfOfPort = getSfPort(bridgeNode, sfDplName);
+ String sfMac = getMacFromExternalIds(bridgeNode, sfDplName);
+ if (sfMac == null) {
+ LOG.warn("handleSff: could not find mac for {} on {}", sfDplName, bridgeNode);
+ return;
+ }
+ //should be sffdplport, but they should all be the same 6633/4790
+ sfcClassifierService.program_sfEgress(dataPathId, sfIpPort, true);
+ sfcClassifierService.program_sfIngress(dataPathId, sfIpPort, sfOfPort, sfIpAddr, sfDplName, true);
+ sfcClassifierService.programStaticArpEntry(dataPathId, 0L, sfMac, sfIpAddr, true);
+ }
+ }
+
+ private boolean isSffOnBridge(Node bridgeNode, ServiceFunctionForwarder serviceFunctionForwarder) {
+ String local_ip = "";
+ Ip ip = sfcUtils.getSffIp(serviceFunctionForwarder);
+ Node ovsdbNode = southbound.readOvsdbNode(bridgeNode);
+ if (ovsdbNode != null) {
+ OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
+ if (ovsdbNodeAugmentation != null && ovsdbNodeAugmentation.getOpenvswitchOtherConfigs() != null) {
+ southbound.getOtherConfig(ovsdbNode, OvsdbTables.OPENVSWITCH, TUNNEL_ENDPOINT_KEY);
+ }
+
+ }
+ return local_ip.equals(String.valueOf(ip.getIp().getValue()));
+ }
+
+ private boolean isSfOnBridge(Node bridgeNode, ServiceFunction serviceFunction) {
+ String sfDplName = sfcUtils.getSfDplName(serviceFunction);
+ long sfOfPort = getSfPort(bridgeNode, sfDplName);
+ return sfOfPort != 0L;
+ }
+
private RenderedServicePath getRenderedServicePath (Ace entry) {
+ RenderedServicePath rsp = null;
RedirectToSfc sfcRedirect = entry.getActions().getAugmentation(RedirectToSfc.class);
LOG.debug("Processing ACL entry = {} sfcRedirect = {}", entry.getRuleName(), sfcRedirect);
if (sfcRedirect == null) {
return null;
}
- String sfcName = sfcRedirect.getRedirectSfc();
+ if (sfcRedirect.getRspName() != null) {
+ rsp = getRenderedServicePathFromRsp(sfcRedirect.getRspName());
+ } else if (sfcRedirect.getSfpName() != null) {
+ LOG.warn("getRenderedServicePath: sfp not handled yet");
+ } else {
+ rsp = getRenderedServicePathFromSfc(entry);
+ }
+ LOG.info("getRenderedServicePath: rsp: {}", rsp);
+ return rsp;
+ }
+
+ private RenderedServicePath getRenderedServicePathFromRsp(String rspName) {
+ return sfcUtils.getRsp(rspName);
+ }
+
+ private RenderedServicePath getRenderedServicePathFromSfc (Ace entry) {
+ RedirectToSfc sfcRedirect = entry.getActions().getAugmentation(RedirectToSfc.class);
+ LOG.debug("Processing ACL entry = {} sfcRedirect = {}", entry.getRuleName(), sfcRedirect);
+ if (sfcRedirect == null) {
+ LOG.warn("processAClEntry: sfcRedirect is null");
+ return null;
+ }
+
+ String sfcName = sfcRedirect.getSfcName();
ServiceFunctionPath sfp = sfcUtils.getSfp(sfcName);
if (sfp == null || sfp.getName() == null) {
LOG.warn("There is no configured SFP with sfcName = {}; so skip installing the ACL entry!!", sfcName);
return null;
}
- LOG.debug("Processing Redirect to SFC = {}, SFP = {}", sfcRedirect.getRedirectSfc(), sfp);
+ LOG.debug("Processing Redirect to SFC = {}, SFP = {}", sfcName, sfp);
// If RSP doesn't exist, create an RSP.
String sfpName = sfp.getName().getValue();
RenderedServicePath rsp = sfcUtils.getRspforSfp(sfpName);
List<OvsdbTerminationPointAugmentation> ovsdbTerminationPointAugmentations =
southbound.getTerminationPointsOfBridge(bridgeNode);
if (!ovsdbTerminationPointAugmentations.isEmpty()) {
- for (OvsdbTerminationPointAugmentation terminationPointAugmentation : ovsdbTerminationPointAugmentations) {
+ for (OvsdbTerminationPointAugmentation terminationPointAugmentation :
+ ovsdbTerminationPointAugmentations) {
if (terminationPointAugmentation.getInterfaceType() ==
SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP.get(NETWORK_TYPE_VXLAN)) {
if (!terminationPointAugmentation.getName().equals(vxGpePortName)) {
private long getOFPort(Node bridgeNode, String portName) {
long ofPort = 0L;
- OvsdbTerminationPointAugmentation port = southbound.extractTerminationPointAugmentation(bridgeNode, portName);
+ OvsdbTerminationPointAugmentation port =
+ southbound.extractTerminationPointAugmentation(bridgeNode, portName);
if (port != null) {
ofPort = southbound.getOFPort(port);
}
private String getMacFromExternalIds(Node bridgeNode, String portName) {
String mac = null;
- OvsdbTerminationPointAugmentation port = southbound.extractTerminationPointAugmentation(bridgeNode, portName);
+ OvsdbTerminationPointAugmentation port = southbound.getTerminationPointOfBridge(bridgeNode, portName);
LOG.info("getMac: portName: {}, bridgeNode: {},,, port: {}", portName, bridgeNode, port);
if (port != null && port.getInterfaceExternalIds() != null) {
mac = southbound.getInterfaceExternalIdsValue(port, Constants.EXTERNAL_ID_VM_MAC);
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxRegCaseBuilder;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.slf4j.Logger;
private static final Logger LOG = LoggerFactory.getLogger(SfcClassifierService.class);
private static final short TABLE_0 = 0;
private static final short UDP_SHORT = 17;
- private static int cookieCounter = 0;
- private static final int FLOW_INGRESSCLASS = 1;
- private static final int FLOW_SFINGRESS = 2;
- private static final int FLOW_SFEGRESS = 3;
- private static final int FLOW_SFARP = 4;
- private static final int FLOW_EGRESSCLASS1 = 5;
- private static final int FLOW_EGRESSCLASS2 = 6;
- private static final int FLOW_SFCTABLE = 7;
+ static int cookieIndex = 0;
+
+ private enum FlowID {
+ FLOW_INGRESSCLASS(1), FLOW_SFINGRESS(2), FLOW_SFEGRESS(3), FLOW_SFARP(4),
+ FLOW_EGRESSCLASSUNUSED(5), FLOW_EGRESSCLASS(6), FLOW_EGRESSCLASSBYPASS(7), FLOW_SFCTABLE(8);
+
+ private int value;
+ FlowID(int value) {
+ this.value = value;
+ }
+
+ }
+
+ //private AtomicLong flowCookieInc = new AtomicLong(0x1L);
+ private BigInteger getCookie(FlowID flowID) {
+ String cookieString = new String().format("1110%02d%010d", flowID.value, cookieIndex++);
+ //new String().format("1100%02d00%04d", flowID.value, flowCookieInc.getAndIncrement());
+ // "1100%02000000d%04d"
+ return new BigInteger(cookieString, 16);
+ }
public SfcClassifierService(Service service) {
super(service);
@Override
public void setDependencies(Object impl) {}
- private BigInteger getCookie(int index) {
- String indexString = new String().format("%02d0000000000%04d", index, cookieCounter++);
- return new BigInteger(indexString, 16);
- }
-
@Override
public void programIngressClassifier(long dataPathId, String ruleName, Matches matches,
NshUtils nshHeader, long vxGpeOfPort, boolean write) {
FlowBuilder flowBuilder = new FlowBuilder();
MatchBuilder matchBuilder = buildMatch(matches);
- //flowBuilder.setMatch(matchBuilder.build());
- flowBuilder.setMatch(MatchUtils.addNxRegMatch(
- matchBuilder,
- new MatchUtils.RegMatch(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL)).build());
+ MatchUtils.addNxRegMatch(matchBuilder,
+ MatchUtils.RegMatch.of(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL));
+ MatchUtils.addNxRegMatch(matchBuilder,
+ MatchUtils.RegMatch.of(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL));
+ flowBuilder.setMatch(matchBuilder.build());
String flowId = "sfcIngressClass_" + ruleName;// + "_" + nshHeader.getNshNsp();
flowBuilder.setId(new FlowId(flowId));
flowBuilder.setFlowName(flowId);
flowBuilder.setHardTimeout(0);
flowBuilder.setIdleTimeout(0);
- flowBuilder.setCookie(new FlowCookie(getCookie(FLOW_INGRESSCLASS)));
- flowBuilder.setCookieMask(new FlowCookie(getCookie(FLOW_INGRESSCLASS)));
+ flowBuilder.setCookie(new FlowCookie(getCookie(FlowID.FLOW_INGRESSCLASS)));
if (write) {
ActionBuilder ab = new ActionBuilder();
FlowBuilder flowBuilder = new FlowBuilder();
MatchBuilder matchBuilder = new MatchBuilder();
- flowBuilder.setMatch(MatchUtils.createInPortMatch(matchBuilder, dataPathId, vxGpeOfPort).build());
+ MatchUtils.createInPortMatch(matchBuilder, dataPathId, vxGpeOfPort);
+ flowBuilder.setMatch(matchBuilder.build());
String flowId = "sfcTable_" + vxGpeOfPort;
flowBuilder.setId(new FlowId(flowId));
flowBuilder.setHardTimeout(0);
flowBuilder.setIdleTimeout(0);
flowBuilder.setPriority(1000);
- flowBuilder.setCookie(new FlowCookie(getCookie(FLOW_SFCTABLE)));
- flowBuilder.setCookieMask(new FlowCookie(getCookie(FLOW_SFCTABLE)));
+ flowBuilder.setCookie(new FlowCookie(getCookie(FlowID.FLOW_SFCTABLE)));
+ flowBuilder.setCookieMask(new FlowCookie(getCookie(FlowID.FLOW_SFCTABLE)));
if (write) {
InstructionsBuilder isb = new InstructionsBuilder();
MatchBuilder matchBuilder = new MatchBuilder();
MatchUtils.createInPortMatch(matchBuilder, dataPathId, vxGpeOfPort);
MatchUtils.addNxNspMatch(matchBuilder, nsp);
- flowBuilder.setMatch(MatchUtils.addNxNsiMatch(matchBuilder, nsi).build());
+ MatchUtils.addNxNsiMatch(matchBuilder, nsi);
+ flowBuilder.setMatch(matchBuilder.build());
String flowId = "sfcEgressClass1_" + vxGpeOfPort;
flowBuilder.setId(new FlowId(flowId));
flowBuilder.setFlowName(flowId);
flowBuilder.setHardTimeout(0);
flowBuilder.setIdleTimeout(0);
- flowBuilder.setCookie(new FlowCookie(getCookie(FLOW_EGRESSCLASS1)));
- flowBuilder.setCookieMask(new FlowCookie(getCookie(FLOW_EGRESSCLASS1)));
+ flowBuilder.setCookie(new FlowCookie(getCookie(FlowID.FLOW_EGRESSCLASSUNUSED)));
+ flowBuilder.setCookieMask(new FlowCookie(getCookie(FlowID.FLOW_EGRESSCLASSUNUSED)));
if (write) {
InstructionsBuilder isb = new InstructionsBuilder();
}
}
- // add 3: same match, add in_port sf, priority=40k, move c2 to tun_id, reg0-1, nsp=0,nsi=0
@Override
- public void programEgressClassifier2(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
- int tunnelOfPort, int tunnelId, boolean write) {
+ public void programEgressClassifier(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
+ long sfOfPort, int tunnelId, boolean write) {
NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
FlowBuilder flowBuilder = new FlowBuilder();
MatchBuilder matchBuilder = new MatchBuilder();
MatchUtils.createInPortMatch(matchBuilder, dataPathId, vxGpeOfPort);
- MatchUtils.addNxRegMatch(matchBuilder,
- new MatchUtils.RegMatch(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL)).build();
MatchUtils.addNxNspMatch(matchBuilder, nsp);
- flowBuilder.setMatch(MatchUtils.addNxNsiMatch(matchBuilder, nsi).build());
+ MatchUtils.addNxNsiMatch(matchBuilder, nsi);
+ flowBuilder.setMatch(matchBuilder.build());
- String flowId = "sfcEgressClass2_" + vxGpeOfPort;
+ String flowId = "sfcEgressClass_" + nsp + "_" + + nsi + "_" + vxGpeOfPort;
flowBuilder.setId(new FlowId(flowId));
FlowKey key = new FlowKey(new FlowId(flowId));
flowBuilder.setBarrier(true);
- flowBuilder.setTableId(getTable());
+ flowBuilder.setTableId(TABLE_0);
flowBuilder.setKey(key);
flowBuilder.setFlowName(flowId);
flowBuilder.setHardTimeout(0);
flowBuilder.setIdleTimeout(0);
- flowBuilder.setCookie(new FlowCookie(getCookie(FLOW_EGRESSCLASS2)));
- flowBuilder.setCookieMask(new FlowCookie(getCookie(FLOW_EGRESSCLASS2)));
+ flowBuilder.setCookie(new FlowCookie(getCookie(FlowID.FLOW_EGRESSCLASS)));
+ flowBuilder.setCookieMask(new FlowCookie(getCookie(FlowID.FLOW_EGRESSCLASS)));
if (write) {
InstructionsBuilder isb = new InstructionsBuilder();
ActionBuilder ab = new ActionBuilder();
- // don't do this, need it to match on the resubmit side and get past table 10 so it isn't reclassified
- //ab.setAction(ActionUtils.nxSetNspAction((long)(0)));
- //ab.setOrder(0);
- //ab.setKey(new ActionKey(0));
- //actionList.add(ab.build());
+ ab.setAction(
+ ActionUtils.nxLoadRegAction(new DstNxRegCaseBuilder().setNxReg(FlowUtils.REG_FIELD).build(),
+ BigInteger.valueOf(FlowUtils.REG_VALUE_FROM_LOCAL)));
+ ab.setOrder(actionList.size());
+ ab.setKey(new ActionKey(actionList.size()));
+ actionList.add(ab.build());
+
+ ab.setAction(ActionUtils.nxMoveNshc2ToTunId());
+ ab.setOrder(actionList.size());
+ ab.setKey(new ActionKey(actionList.size()));
+ actionList.add(ab.build());
- ab.setAction(ActionUtils.nxResubmitAction(tunnelOfPort, TABLE_0));
+ ab.setAction(ActionUtils.nxResubmitAction((int)sfOfPort, TABLE_0));
ab.setOrder(actionList.size());
ab.setKey(new ActionKey(actionList.size()));
actionList.add(ab.build());
isb.setInstruction(instructions);
flowBuilder.setInstructions(isb.build());
writeFlow(flowBuilder, nodeBuilder);
+ } else {
+ removeFlow(flowBuilder, nodeBuilder);
+ }
+ }
+
+ @Override
+ public void programEgressClassifierBypass(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
+ long sfOfPort, int tunnelId, boolean write) {
+ NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
+ FlowBuilder flowBuilder = new FlowBuilder();
+
+ MatchBuilder matchBuilder = new MatchBuilder();
+ MatchUtils.createInPortMatch(matchBuilder, dataPathId, sfOfPort);
+ MatchUtils.addNxRegMatch(matchBuilder,
+ MatchUtils.RegMatch.of(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL));
+ MatchUtils.addNxNspMatch(matchBuilder, nsp);
+ MatchUtils.addNxNsiMatch(matchBuilder, nsi);
+ flowBuilder.setMatch(matchBuilder.build());
+
+ String flowId = "sfcEgressClassBypass_" + nsp + "_" + + nsi + "_" + sfOfPort;
+ flowBuilder.setId(new FlowId(flowId));
+ FlowKey key = new FlowKey(new FlowId(flowId));
+ flowBuilder.setBarrier(true);
+ flowBuilder.setTableId(TABLE_0);
+ flowBuilder.setKey(key);
+ flowBuilder.setFlowName(flowId);
+ flowBuilder.setHardTimeout(0);
+ flowBuilder.setIdleTimeout(0);
+ flowBuilder.setCookie(new FlowCookie(getCookie(FlowID.FLOW_EGRESSCLASSBYPASS)));
+ flowBuilder.setCookieMask(new FlowCookie(getCookie(FlowID.FLOW_EGRESSCLASSBYPASS)));
+ flowBuilder.setPriority(40000); //Needs to be above default priority of 32768
+
+ if (write) {
+ InstructionsBuilder isb = new InstructionsBuilder();
+ List<Instruction> instructions = Lists.newArrayList();
+
+ InstructionBuilder ib;
+ ib = this.getMutablePipelineInstructionBuilder();
+ ib.setOrder(0);
+ ib.setKey(new InstructionKey(0));
+ instructions.add(ib.build());
+ isb.setInstruction(instructions);
+ flowBuilder.setInstructions(isb.build());
+ writeFlow(flowBuilder, nodeBuilder);
} else {
removeFlow(flowBuilder, nodeBuilder);
}
MatchBuilder matchBuilder = new MatchBuilder();
MatchUtils.createIpProtocolMatch(matchBuilder, UDP_SHORT);
MatchUtils.addLayer4Match(matchBuilder, UDP_SHORT, 0, dstPort);
- flowBuilder.setMatch(MatchUtils.addNxRegMatch(
- matchBuilder, new MatchUtils.RegMatch(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL)).build());
+ MatchUtils.addNxRegMatch(matchBuilder,
+ MatchUtils.RegMatch.of(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL));
+ flowBuilder.setMatch(matchBuilder.build());
String flowId = "sfEgress_" + dstPort;
flowBuilder.setId(new FlowId(flowId));
flowBuilder.setFlowName(flowId);
flowBuilder.setHardTimeout(0);
flowBuilder.setIdleTimeout(0);
- flowBuilder.setCookie(new FlowCookie(getCookie(FLOW_SFEGRESS)));
- flowBuilder.setCookieMask(new FlowCookie(getCookie(FLOW_SFEGRESS)));
+ flowBuilder.setCookie(new FlowCookie(getCookie(FlowID.FLOW_SFEGRESS)));
+ flowBuilder.setCookieMask(new FlowCookie(getCookie(FlowID.FLOW_SFEGRESS)));
if (write) {
InstructionBuilder ib = new InstructionBuilder();
MatchUtils.createIpProtocolMatch(matchBuilder, UDP_SHORT);
Ipv4Prefix ipCidr = MatchUtils.iPv4PrefixFromIPv4Address(ipAddress);
MatchUtils.createDstL3IPv4Match(matchBuilder, new Ipv4Prefix(ipCidr));
- flowBuilder.setMatch(MatchUtils.addLayer4Match(matchBuilder, UDP_SHORT, 0, dstPort).build());
+ MatchUtils.addLayer4Match(matchBuilder, UDP_SHORT, 0, dstPort);
+ flowBuilder.setMatch(matchBuilder.build());
String flowId = "sfIngress_" + dstPort + "_" + ipAddress;
flowBuilder.setId(new FlowId(flowId));
flowBuilder.setFlowName(flowId);
flowBuilder.setHardTimeout(0);
flowBuilder.setIdleTimeout(0);
- flowBuilder.setCookie(new FlowCookie(getCookie(FLOW_SFINGRESS)));
- flowBuilder.setCookieMask(new FlowCookie(getCookie(FLOW_SFINGRESS)));
+ flowBuilder.setCookie(new FlowCookie(getCookie(FlowID.FLOW_SFINGRESS)));
+ flowBuilder.setCookieMask(new FlowCookie(getCookie(FlowID.FLOW_SFINGRESS)));
if (write) {
InstructionBuilder ib = new InstructionBuilder();
MacAddress macAddress = new MacAddress(macAddressStr);
MatchBuilder matchBuilder = new MatchBuilder();
+ MatchUtils.createInPortReservedMatch(matchBuilder, dataPathId, OutputPortValues.LOCAL.toString());
MatchUtils.createEtherTypeMatch(matchBuilder, new EtherType(Constants.ARP_ETHERTYPE));
MatchUtils.createArpDstIpv4Match(matchBuilder, MatchUtils.iPv4PrefixFromIPv4Address(ipAddress));
flowBuilder.setMatch(matchBuilder.build());
flowBuilder.setFlowName(flowId);
flowBuilder.setHardTimeout(0);
flowBuilder.setIdleTimeout(0);
- flowBuilder.setCookie(new FlowCookie(getCookie(FLOW_SFARP)));
- flowBuilder.setCookieMask(new FlowCookie(getCookie(FLOW_SFARP)));
+ flowBuilder.setCookie(new FlowCookie(getCookie(FlowID.FLOW_SFARP)));
+ flowBuilder.setCookieMask(new FlowCookie(getCookie(FlowID.FLOW_SFARP)));
if (write == true) {
InstructionBuilder ib = new InstructionBuilder();
actionList.add(ab.build());
// Set ARP OP
- ab.setAction(ActionUtils.nxLoadArpOpAction(BigInteger.valueOf(0x02L)));
+ ab.setAction(ActionUtils.nxLoadArpOpAction(BigInteger.valueOf(FlowUtils.ARP_OP_REPLY)));
ab.setOrder(2);
ab.setKey(new ActionKey(2));
actionList.add(ab.build());
private static final String SF2IP = "10.2.1.2";
private static final String SF1DPLNAME = "sf1";
private static final String SF2DPLNAME = "sf2";
- private static final String SFF1IP = "127.0.0.1";
- private static final String SFF2IP = "127.0.0.1";
+ private static final String SFF1IP = "127.0.0.1"; //"192.168.1.129"
+ private static final String SFF2IP = "192.168.1.129";//"127.0.0.1";
private static final String SFF1NAME = "SFF1";
private static final String SFF2NAME = "SFF2";
private static final String SFFDPL1NAME = "vxgpe";
}
public ActionsBuilder actionsBuilder(ActionsBuilder actionsBuilder, String sfcName) {
- RedirectToSfcBuilder redirectToSfcBuilder = new RedirectToSfcBuilder().setRedirectSfc(sfcName);
+ RedirectToSfcBuilder redirectToSfcBuilder = new RedirectToSfcBuilder().setSfcName(sfcName);
return actionsBuilder.addAugmentation(RedirectToSfc.class, redirectToSfcBuilder.build());
}
public static final String OVSDB_URI_PREFIX = "ovsdb";
public static final String BRIDGE_URI_PREFIX = "bridge";
public static final String TP_URI_PREFIX = "termination-point";
+ public static final String DISABLE_IN_BAND = "disable-in-band";
public static final ImmutableBiMap<Class<? extends OvsdbBridgeProtocolBase>,String> OVSDB_PROTOCOL_MAP
= new ImmutableBiMap.Builder<Class<? extends OvsdbBridgeProtocolBase>,String>()
import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronPort;
import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronRouter;
import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronRouter_Interface;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityRule;
import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSubnet;
import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
private NeutronLoadBalancer loadBalancer;
private NeutronLoadBalancerPool loadBalancerPool;
private NeutronLoadBalancerPoolMember loadBalancerPoolMember;
+ private NeutronSecurityRule neutronSecurityRule;
NorthboundEvent(NeutronPort port, Action action) {
super(HandlerType.NEUTRON_PORT, action);
this.loadBalancerPoolMember = loadBalancerPoolMember;
}
+ NorthboundEvent(NeutronSecurityRule neutronSecurityRule, Action action) {
+ super(HandlerType.NEUTRON_PORT_SECURITY, action);
+ this.neutronSecurityRule = neutronSecurityRule;
+ }
+
public NeutronPort getPort() {
return port;
}
public NeutronLoadBalancerPoolMember getLoadBalancerPoolMember() {
return loadBalancerPoolMember;
}
+ public NeutronSecurityRule getNeutronSecurityRule() {
+ return neutronSecurityRule;
+ }
@Override
public String toString() {
+ ", loadBalancer=" + loadBalancer
+ ", loadBalancerPool=" + loadBalancerPool
+ ", loadBalancerPoolMember=" + loadBalancerPoolMember
+ + ", neutronsecurityRule=" + neutronSecurityRule
+ "]";
}
result = prime * result + ((routerInterface == null) ? 0 : routerInterface.hashCode());
result = prime * result + ((neutronFloatingIP == null) ? 0 : neutronFloatingIP.hashCode());
result = prime * result + ((neutronNetwork == null) ? 0 : neutronNetwork.hashCode());
+ result = prime * result + ((neutronSecurityRule == null) ? 0 : neutronSecurityRule.hashCode());
return result;
}
} else if (!loadBalancerPoolMember.equals(other.loadBalancerPoolMember)) {
return false;
}
+ if (neutronSecurityRule == null) {
+ if (other.neutronSecurityRule != null) {
+ return false;
+ }
+ } else if (!neutronSecurityRule.equals(other.neutronSecurityRule)) {
+ return false;
+ }
return true;
}
}
package org.opendaylight.ovsdb.openstack.netvirt;
import java.net.HttpURLConnection;
+import java.util.ArrayList;
+import java.util.List;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronPort;
import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup;
import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityRule;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.Neutron_IPs;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronPortCRUD;
import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronSecurityGroupAware;
import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronSecurityRuleAware;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
import org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher;
+import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityServicesManager;
import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
import org.osgi.framework.ServiceReference;
import org.slf4j.Logger;
implements INeutronSecurityGroupAware, INeutronSecurityRuleAware, ConfigInterface {
private static final Logger LOG = LoggerFactory.getLogger(PortSecurityHandler.class);
+ private volatile INeutronPortCRUD neutronPortCache;
+ private volatile SecurityServicesManager securityServicesManager;
@Override
public int canCreateNeutronSecurityGroup(NeutronSecurityGroup neutronSecurityGroup) {
@Override
public void neutronSecurityRuleCreated(NeutronSecurityRule neutronSecurityRule) {
- int result = canCreateNeutronSecurityRule(neutronSecurityRule);
- if (result != HttpURLConnection.HTTP_CREATED) {
- LOG.debug("Neutron Security Group creation failed {} ", result);
- }
+ enqueueEvent(new NorthboundEvent(neutronSecurityRule, Action.ADD));
}
@Override
@Override
public void neutronSecurityRuleDeleted(NeutronSecurityRule neutronSecurityRule) {
- int result = canDeleteNeutronSecurityRule(neutronSecurityRule);
- if (result != HttpURLConnection.HTTP_OK) {
- LOG.error(" delete Neutron Security Rule validation failed for result - {} ", result);
- }
+ enqueueEvent(new NorthboundEvent(neutronSecurityRule, Action.DELETE));
}
/**
}
NorthboundEvent ev = (NorthboundEvent) abstractEvent;
switch (ev.getAction()) {
- // TODO: add handling of events here, once callbacks do something
- // other than logging.
+ case ADD:
+ processNeutronSecurityRuleAdded(ev.getNeutronSecurityRule());
+ break;
+ case DELETE:
+ processNeutronSecurityRuleDeleted(ev.getNeutronSecurityRule());
+ break;
default:
LOG.warn("Unable to process event action {}", ev.getAction());
break;
}
}
+ private void processNeutronSecurityRuleAdded(NeutronSecurityRule neutronSecurityRule) {
+ List<NeutronPort> portList = getPortWithSecurityGroup(neutronSecurityRule.getSecurityRuleGroupID());
+ for (NeutronPort port:portList) {
+ syncSecurityGroup(neutronSecurityRule,port,neutronSecurityRule.getSecurityRuleGroupID(),true);
+ }
+ }
+
+ private void processNeutronSecurityRuleDeleted(NeutronSecurityRule neutronSecurityRule) {
+ List<NeutronPort> portList = getPortWithSecurityGroup(neutronSecurityRule.getSecurityRuleGroupID());
+ for (NeutronPort port:portList) {
+ syncSecurityGroup(neutronSecurityRule,port,neutronSecurityRule.getSecurityRuleGroupID(),false);
+ }
+ }
+
+ private void syncSecurityGroup(NeutronSecurityRule securityRule,NeutronPort port,
+ String neutronSecurityGroupId,boolean write) {
+
+ if (null != securityRule.getSecurityRemoteGroupID()) {
+ List<Neutron_IPs> vmIpList = securityServicesManager
+ .getVmListForSecurityGroup(port.getID(), neutronSecurityGroupId);
+ for (Neutron_IPs vmIp :vmIpList ) {
+ securityServicesManager.syncSecurityRule(port, securityRule, vmIp, write);
+ }
+ } else {
+ securityServicesManager.syncSecurityRule(port, securityRule, null, write);
+ }
+ }
+
+ private List<NeutronPort> getPortWithSecurityGroup(String securityGroupUuid) {
+
+ List<NeutronPort> neutronPortList = neutronPortCache.getAllPorts();
+ List<NeutronPort> neutronPortInSG = new ArrayList<NeutronPort>();
+ for (NeutronPort neutronPort:neutronPortList) {
+ List<NeutronSecurityGroup> securityGroupList = neutronPort.getSecurityGroups();
+ for (NeutronSecurityGroup neutronSecurityGroup:securityGroupList) {
+ if (neutronSecurityGroup.getID().equals(securityGroupUuid)) {
+ neutronPortInSG.add(neutronPort);
+ break;
+ }
+ }
+ }
+ return neutronPortInSG;
+ }
+
@Override
public void setDependencies(ServiceReference serviceReference) {
eventDispatcher =
(EventDispatcher) ServiceHelper.getGlobalInstance(EventDispatcher.class, this);
eventDispatcher.eventHandlerAdded(serviceReference, this);
+ neutronPortCache =
+ (INeutronPortCRUD) ServiceHelper.getGlobalInstance(INeutronPortCRUD.class, this);
+ securityServicesManager =
+ (SecurityServicesManager) ServiceHelper.getGlobalInstance(SecurityServicesManager.class, this);
}
@Override
* @return a List in the format {eth1, eth2} given bridge_mappings=physnet1:eth1,physnet2:eth2
*/
List<String> getAllPhysicalInterfaceNames(Node node);
+
+ /*
+ * Return br-ex interface configured in the bridge_mappings.
+ * Return null if br-ex is not configured in bridge_mappings.
+ * @param node the {@link Node} to query
+ * @param externalNetwork
+ * @return the interface as a string like eth3 given bridge_mappings=br-ex:eth3
+ */
+ String getExternalInterfaceName (Node node, String externalNetwork);
+
}
return isCreated;
}
+
+
+ @Override
+ public String getExternalInterfaceName (Node node, String extNetwork) {
+ String phyIf = null;
+ String providerMaps = southbound.getOtherConfig(node, OvsdbTables.OPENVSWITCH,
+ configurationService.getProviderMappingsKey());
+ if (providerMaps != null) {
+ for (String map : providerMaps.split(",")) {
+ String[] pair = map.split(":");
+ if (pair[0].equals(extNetwork)) {
+ phyIf = pair[1];
+ break;
+ }
+ }
+ }
+ if (phyIf == null) {
+ LOG.error("External interface not found for Node: {}, Network {}",
+ node, extNetwork);
+ }
+ else {
+ LOG.info("External interface found for Node: {}, Network {} is {}",node,extNetwork,phyIf);
+ }
+ return phyIf;
+ }
+
+
+
@Override
public String getPhysicalInterfaceName (Node node, String physicalNetwork) {
String phyIf = null;
LOG.error("Add Port {} to Bridge {} failed", portNameExt, brExt);
return false;
}
+ String extNetName = getExternalInterfaceName(extBridgeNode, brExt);
+ if ( extNetName != null) {
+ if (!addPortToBridge(extBridgeNode, brExt, extNetName)) {
+ LOG.error("Add External Port {} to Bridge {} failed", extNetName, brExt);
+ return false;
+ }
+ LOG.info("Add External Port {} to Ext Bridge {} success", extNetName, brExt);
+ }
}
-
/* For vlan network types add physical port to br-int. */
if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) {
String phyNetName = this.getPhysicalInterfaceName(bridgeNode, network.getProviderPhysicalNetwork());
}
}
- LOG.debug("createBridges: node: {}, status: success", bridgeNode);
+ LOG.info("createBridges: node: {}, status: success", bridgeNode);
return true;
}
import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.impl.NeutronNetworkChangeListener;
import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.impl.NeutronPortChangeListener;
import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.impl.NeutronRouterChangeListener;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.impl.NeutronSecurityRuleDataChangeListener;
import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.impl.NeutronSubnetChangeListener;
import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.impl.NeutronLoadBalancerPoolChangeListener;
import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.impl.NeutronLoadBalancerPoolMemberChangeListener;
new NeutronFloatingIPChangeListener(db);
new NeutronLoadBalancerPoolChangeListener(db);
new NeutronLoadBalancerPoolMemberChangeListener(db);
+ new NeutronSecurityRuleDataChangeListener(db);
}
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIds;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigsKey;
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.bridge.attributes.ControllerEntryBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
ovsdbBridgeAugmentationBuilder.setFailMode(
MdsalHelper.OVSDB_FAIL_MODE_MAP.inverse().get("secure"));
+ BridgeOtherConfigsBuilder bridgeOtherConfigsBuilder = new BridgeOtherConfigsBuilder();
+ bridgeOtherConfigsBuilder.setBridgeOtherConfigKey(MdsalHelper.DISABLE_IN_BAND);
+ bridgeOtherConfigsBuilder.setBridgeOtherConfigValue("true");
+ bridgeOtherConfigsBuilder.setBridgeOtherConfigKey(MdsalHelper.DISABLE_IN_BAND);
+ List<BridgeOtherConfigs> bridgeOtherConfigsList = new ArrayList<>();
+ bridgeOtherConfigsList.add(bridgeOtherConfigsBuilder.build());
+ ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(bridgeOtherConfigsList);
setManagedByForBridge(ovsdbBridgeAugmentationBuilder, ovsdbNode.getKey());
if (isOvsdbNodeDpdk(ovsdbNode)) {
ovsdbBridgeAugmentationBuilder.setDatapathType(DatapathTypeNetdev.class);
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.EthertypeV4;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.EthertypeV6;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolBase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolHttp;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolHttps;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolIcmp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolIcmpV6;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolTcp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolUdp;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.rules.attributes.SecurityRules;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.rules.attributes.security.rules.SecurityRule;
private static final Logger LOG = LoggerFactory.getLogger(NeutronSecurityRuleDataChangeListener.class);
private static final ImmutableBiMap<Class<? extends DirectionBase>, String> DIRECTION_MAP
- = new ImmutableBiMap.Builder<Class<? extends DirectionBase>, String>()
- .put(DirectionEgress.class, "egress")
- .put(DirectionIngress.class, "ingress").build();
- private static final ImmutableBiMap<Class<? extends ProtocolBase>, String> PROTOCOL_MAP
- = new ImmutableBiMap.Builder<Class<? extends ProtocolBase>, String>()
- .put(ProtocolHttp.class, "HTTP")
- .put(ProtocolHttps.class, "HTTPS")
- .put(ProtocolIcmp.class, "ICMP")
- .put(ProtocolTcp.class, "TCP")
+ = new ImmutableBiMap.Builder<Class<? extends DirectionBase>, String>()
+ .put(DirectionEgress.class, "egress")
+ .put(DirectionIngress.class, "ingress").build();
+ private static final ImmutableBiMap<Class<? extends ProtocolBase>,String> PROTOCOL_MAP
+ = new ImmutableBiMap.Builder<Class<? extends ProtocolBase>,String>()
+ .put(ProtocolIcmp.class,"icmp")
+ .put(ProtocolTcp.class,"tcp")
+ .put(ProtocolUdp.class,"udp")
+ .put(ProtocolIcmpV6.class,"icmpv6")
.build();
- private static final ImmutableBiMap<Class<? extends EthertypeBase>, String> ETHERTYPE_MAP
- = new ImmutableBiMap.Builder<Class<? extends EthertypeBase>, String>()
- .put(EthertypeV4.class, "v4")
- .put(EthertypeV6.class, "v6")
+ private static final ImmutableBiMap<Class<? extends EthertypeBase>,String> ETHERTYPE_MAP
+ = new ImmutableBiMap.Builder<Class<? extends EthertypeBase>,String>()
+ .put(EthertypeV4.class,"IPv4")
+ .put(EthertypeV6.class,"IPv6")
.build();
private ListenerRegistration<DataChangeListener> registration;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
+import org.mockito.Mock;
import org.mockito.Mockito;
import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup;
import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityRule;
@InjectMocks private PortSecurityHandler portSecurityHandler;
private PortSecurityHandler posrtSecurityHandlerSpy;
+ @Mock EventDispatcher eventDispatcher;
@Before
public void setUp() {
assertEquals("Error, did not return the correct HTTP flag", HttpURLConnection.HTTP_CREATED, portSecurityHandler.canCreateNeutronSecurityRule(mock(NeutronSecurityRule.class)));
posrtSecurityHandlerSpy.neutronSecurityRuleCreated(any(NeutronSecurityRule.class));
- verify(posrtSecurityHandlerSpy, times(1)).canCreateNeutronSecurityRule(any(NeutronSecurityRule.class));
+ verify(posrtSecurityHandlerSpy, times(1)).enqueueEvent(any(AbstractEvent.class));
}
@Test
assertEquals("Error, did not return the correct HTTP flag", HttpURLConnection.HTTP_OK, portSecurityHandler.canDeleteNeutronSecurityRule(mock(NeutronSecurityRule.class)));
posrtSecurityHandlerSpy.neutronSecurityRuleDeleted(any(NeutronSecurityRule.class));
- verify(posrtSecurityHandlerSpy, times(1)).canDeleteNeutronSecurityRule(any(NeutronSecurityRule.class));
+ verify(posrtSecurityHandlerSpy, times(1)).enqueueEvent(any(AbstractEvent.class));
}
@Test
--- /dev/null
+{
+ "id":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+ "name":"Ovsdb HwvtepSouthbound",
+ "timestamp":1424977469540,
+ "order":[
+ "e9ff6957-4dc2-9257-c0c6-21560bfd5de2",
+ "ee151670-85a0-30ec-b22b-5defe7b66e0b",
+ "6de1ede7-817c-ccbb-3df9-ef510bdaf583",
+ "6e7c88e4-485d-ab9f-4c3a-cc235e022905",
+ "92ee7422-5b08-6d63-2b95-961ec0e18ffa",
+ "e92ac963-daaf-0899-c3e8-a00d897be0e2",
+ "9bc22ca7-049c-af51-7c12-6bf71044b2ec",
+ "f6d300f7-380a-d090-0d4a-2b2ddefe5104",
+ "f9f71d74-a49d-b190-d929-b6772ce0ba73",
+ "18032e93-3bc5-9976-4525-fe1e77e98207",
+ "22354294-1d01-cebf-180c-d609747be9bc",
+ "c8e8f3fd-3bfb-aafa-e3ec-a671a942f426",
+ "d362ddc4-1c5f-67d5-e354-c2a8d2ba9d79",
+ "538c71b3-e3e6-f01b-cc4c-d2b686686aa8"
+ ],
+ "owner":0,
+ "sharedWithTeam":false,
+ "synced":false,
+ "subscribed":false,
+ "hasRequests":true,
+ "requests":[
+ {
+ "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+ "id":"18032e93-3bc5-9976-4525-fe1e77e98207",
+ "name":"Delete Specific Config Logical Switch",
+ "description":"This restconf request delete specific logical switch from the config data store.",
+ "url":"http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640%2Flogicalswitch%2Fls0",
+ "method":"DELETE",
+ "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
+ "data":[],
+ "dataMode":"params",
+ "timestamp":0,
+ "version":2,
+ "time":1447335528744
+ },
+ {
+ "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+ "id":"22354294-1d01-cebf-180c-d609747be9bc",
+ "name":"Get All Operational Topology",
+ "description":"This restconf request will fetch the operational topology. Operational topology details are fetch by hwvtepsouthbound plugin from all the connected hwvtep node.",
+ "url":"http://{{controllerHost}}:8181/restconf/operational/network-topology:network-topology/",
+ "method":"GET",
+ "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
+ "data":[],
+ "dataMode":"params",
+ "timestamp":0,
+ "version":2
+ },
+ {
+ "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+ "id":"538c71b3-e3e6-f01b-cc4c-d2b686686aa8",
+ "name":"Get Specific Operational Logical Switch",
+ "description":"This restconf request fetch the operational for specific Logical Switch",
+ "url":"http://{{controllerHost}}:8181/restconf/operational/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640%2logicalswitch%2ls0",
+ "method":"GET",
+ "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
+ "data":"{\n \"network-topology:node\": [\n {\n \"node-id\": \"hwvtep://{{hwvtepNodeIp}}:6640/logicalswitch/ls0\",\n \"hwvtep-node-description\": \"\",\n \"hwvtep-node-name\": \"ls0\",\n \"tunnel-key\": \"10000\"\n }\n ]\n}",
+ "dataMode":"raw",
+ "timestamp":0,
+ "version":2,
+ "time":1447335701900
+ },
+ {
+ "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+ "id":"6de1ede7-817c-ccbb-3df9-ef510bdaf583",
+ "name":"Create Specific Config HwvtepNode",
+ "description":"Fire this Restconf request if you want to initiate the connection to hwvtep node from controller. It assumes that hwvtep node is listening for tcp connection in passive mode.",
+ "url":"http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/",
+ "method":"POST",
+ "headers":"Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+ "data":"{\n \"network-topology:node\": [\n {\n \"node-id\": \"hwvtep://{{hwvtepNodeIp}}:6640\",\n \"connection-info\": {\n \"hwvtep:remote-port\": 6640,\n \"hwvtep:remote-ip\": \"{{hwvtepNodeIp}}\"\n }\n }\n ]\n}",
+ "dataMode":"raw",
+ "timestamp":0,
+ "version":2,
+ "time":1447334840814
+ },
+ {
+ "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+ "id":"6e7c88e4-485d-ab9f-4c3a-cc235e022905",
+ "name":"Update Specific Config HwvtepNode",
+ "description":"Fire this Restconf request if you want to update the connection to Hwvtep node from controller.",
+ "url":"http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640",
+ "method":"PUT",
+ "headers":"Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+ "data":"{\n \"network-topology:node\": [\n {\n \"node-id\": \"hwvtep://{{hwvtepNodeIp}}:6640\",\n \"connection-info\": {\n \"hwvtep:remote-port\": 6640,\n \"hwvtep:remote-ip\": \"{{hwvtepNodeIp}}\"\n }\n }\n ]\n}",
+ "dataMode":"raw",
+ "timestamp":0,
+ "version":2,
+ "time":1447334483164
+ },
+ {
+ "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+ "id":"92ee7422-5b08-6d63-2b95-961ec0e18ffa",
+ "name":"Get Specific Config HwvtepNode",
+ "description":"This restconf request fetch the configration for specific hwvtep node.",
+ "url":"http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640",
+ "method":"GET",
+ "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
+ "data":"{\n \"network-topology:node\": [\n {\n \"node-id\": \"hwvtep://{{hwvtepNodeIp}}:6640\",\n \"connection-info\": {\n \"hwvtep:remote-port\": 6640,\n \"hwvtep:remote-ip\": \"{{hwvtepNodeIp}}\"\n }\n }\n ]\n}",
+ "dataMode":"raw",
+ "timestamp":0,
+ "version":2,
+ "time":1447334914971
+ },
+ {
+ "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+ "id":"9bc22ca7-049c-af51-7c12-6bf71044b2ec",
+ "name":"Create Specific Config Logical Switch",
+ "description":"Fire this Restconf request if you want to create a logical switch.",
+ "url":"http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/",
+ "method":"POST",
+ "headers":"Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+ "data":"{\n \"network-topology:node\": [\n {\n \"node-id\": \"hwvtep://{{hwvtepNodeIp}}:6640/logicalswitch/ls0\",\n \"hwvtep-node-description\": \"\",\n \"hwvtep-node-name\": \"ls0\",\n \"tunnel-key\": \"10000\",\n \"managed-by\": \"/network-topology:network-topology/network-topology:topology[network-topology:topology-id='hwvtep:1']/network-topology:node[network-topology:node-id='hwvtep://{{hwvtepNodeIp}}:6640']\" \n }\n ]\n}",
+ "dataMode":"raw",
+ "timestamp":0,
+ "version":2,
+ "time":1447340822378
+ },
+ {
+ "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+ "id":"c8e8f3fd-3bfb-aafa-e3ec-a671a942f426",
+ "name":"Get Operational Hwvtep Topology",
+ "description":"",
+ "url":"http://{{controllerHost}}:8181/restconf/operational/network-topology:network-topology/topology/hwvtep:1/",
+ "method":"GET",
+ "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
+ "data":"{\n \"network-topology:node\": [\n {\n \"node-id\": \"hwvtep://{{hwvtepNodeIp}}:6640\",\n \"connection-info\": {\n \"hwvtep:remote-port\": 6640,\n \"hwvtep:remote-ip\": \"{{hwvtepNodeIp}}\"\n }\n }\n ]\n}",
+ "dataMode":"raw",
+ "timestamp":0,
+ "version":2,
+ "time":1447335830695
+ },
+ {
+ "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+ "id":"d362ddc4-1c5f-67d5-e354-c2a8d2ba9d79",
+ "name":"Get Specific Operational HwvtepNode",
+ "description":"This restconf request fetch the operational for specific HwvtepNode",
+ "url":"http://{{controllerHost}}:8181/restconf/operational/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640",
+ "method":"GET",
+ "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
+ "data":"{\n \"network-topology:node\": [\n {\n \"node-id\": \"hwvtep://{{hwvtepNodeIp}}:6640/logicalswitch/ls0\",\n \"hwvtep-node-description\": \"\",\n \"hwvtep-node-name\": \"ls0\",\n \"tunnel-key\": \"10000\"\n }\n ]\n}",
+ "dataMode":"raw",
+ "timestamp":0,
+ "version":2,
+ "time":1447335686540
+ },
+ {
+ "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+ "id":"e92ac963-daaf-0899-c3e8-a00d897be0e2",
+ "name":"Delete Specific Config HwvtepNode",
+ "description":"This restconf request delete any node (ovsdb node or bridge node) from the config data store. You can use the same request to delete the ovsdb node by using the following URI: http://localhost:8080/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F10.10.10.10:22222",
+ "url":"http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640",
+ "method":"DELETE",
+ "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
+ "data":[],
+ "dataMode":"params",
+ "timestamp":0,
+ "version":2
+ },
+ {
+ "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+ "id":"e9ff6957-4dc2-9257-c0c6-21560bfd5de2",
+ "name":"Get All Config Topology",
+ "description":"Fetch all the config topology from configuration data store.",
+ "url":"http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/",
+ "method":"GET",
+ "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
+ "data":"{\n \"network-topology:node\": [\n {\n \"node-id\": \"hwvtep://{{hwvtepNodeIp}}:6640\",\n \"connection-info\": {\n \"hwvtep:remote-port\": 6640,\n \"hwvtep:remote-ip\": \"{{hwvtepNodeIp}}\"\n }\n }\n ]\n}",
+ "dataMode":"raw",
+ "timestamp":0,
+ "version":2,
+ "time":1447311894927
+ },
+ {
+ "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+ "id":"ee151670-85a0-30ec-b22b-5defe7b66e0b",
+ "name":"Get Config Hwvtep Topology",
+ "description":"Fetch the config hwvtep topology from configuration data store.",
+ "url":"http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/hwvtep:1/",
+ "method":"GET",
+ "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
+ "data":"{\n \"network-topology:node\": [\n {\n \"node-id\": \"hwvtep://{{hwvtepNodeIp}}:6640\",\n \"connection-info\": {\n \"hwvtep:remote-port\": 6640,\n \"hwvtep:remote-ip\": \"{{hwvtepNodeIp}}\"\n }\n }\n ]\n}",
+ "dataMode":"raw",
+ "timestamp":0,
+ "version":2,
+ "time":1447335823182
+ },
+ {
+ "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+ "id":"f6d300f7-380a-d090-0d4a-2b2ddefe5104",
+ "name":"Create Specific Config Logical Switch",
+ "description":"Fire this request if you want to update specific logical switch.",
+ "url":"http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640%2Flogicalswitch%2Fls0",
+ "method":"PUT",
+ "headers":"Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+ "data":"{\n \"network-topology:node\": [\n {\n \"node-id\": \"hwvtep://{{hwvtepNodeIp}}:6640/logicalswitch/ls0\",\n \"hwvtep-node-description\": \"\",\n \"hwvtep-node-name\": \"ls0\",\n \"tunnel-key\": \"10000\",\n \"managed-by\": \"/network-topology:network-topology/network-topology:topology[network-topology:topology-id='hwvtep:1']/network-topology:node[network-topology:node-id='hwvtep://{{hwvtepNodeIp}}:6640']\" \n }\n ]\n}",
+ "dataMode":"raw",
+ "timestamp":0,
+ "version":2,
+ "time":1447340847211
+ },
+ {
+ "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+ "id":"f9f71d74-a49d-b190-d929-b6772ce0ba73",
+ "name":"Get Specific Config Logical Switch",
+ "description":"This restconf request fetch configuration for specific logical switch.",
+ "url":"http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640%2Flogicalswitch%2Fls0",
+ "method":"GET",
+ "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
+ "data":"{\n \"network-topology:node\": [\n {\n \"node-id\": \"hwvtep://{{hwvtepNodeIp}}:6640/logicalswitch/ls0\",\n \"hwvtep-node-description\": \"\",\n \"hwvtep-node-name\": \"ls0\",\n \"tunnel-key\": \"10000\"\n }\n ]\n}",
+ "dataMode":"raw",
+ "timestamp":0,
+ "version":2,
+ "time":1447335408595
+ }
+ ]
+}
- showOvsdbMdsal.py : Dumps mdsal related info from running ODL that is related to ovsdb and netvirt. Use 'showOvsdbMdsal.py -h' for usage
- ODL-Clustering.json.postman_collection : Collection contains Restconf request to fetch clustering service related data to check the state of 3 node cluster and inventory/topology shards.
- - Please import and load 3-Node-Cluster-Setup-Environment-Variables.postman_environment file, because Restconf request present in this collection depends on the variable defined in this collection.
+ - Please import and load 3-Node-Cluster-Setup-Environment-Variables.postman_environment file, because Restconf request present in this collection depends on the variable defined in this collection.
- Ovsdb-Southbound-Collection-for-Single-Node-Cluster.json.postman_collection : Collection contains Restconf request for doing CRUD operations (connection, bridge, termination point) on southbound plugin running in standalone controller.
- - Please import and load Single-Node-Cluster-Setup-Environment-Variables.postman_environment file, because Restconf request present in this collection depends on the variable defined in this collection.
+ - Please import and load Single-Node-Cluster-Setup-Environment-Variables.postman_environment file, because Restconf request present in this collection depends on the variable defined in this collection.
-- Ovsdb-Southbound-Collection-for-3-Node-Cluster.json.postman_collection :
- - Please import and load 3-Node-Cluster-Setup-Environment-Variables.postman_environment file, because Restconf request present in this collection depends on the variable defined in this collection.
+- Ovsdb-Southbound-Collection-for-3-Node-Cluster.json.postman_collection :
+ - Please import and load 3-Node-Cluster-Setup-Environment-Variables.postman_environment file, because Restconf request present in this collection depends on the variable defined in this collection.
- Single-Node-Cluster-Setup-Environment-Variables.postman_environment : Postman environment file that defines variables for Restconf request for southbound plugin running in Single controller instance
- 3-Node-Cluster-Setup-Environment-Variables.postman_environment : Postman environment file that defines variables for Restconf request for southbound plugin running in 3 node cluster environment
- NetvirtSfc.json.postman_collection : Collection of REST-APIs to interact with Netvirt-Sfc.
+
+- Ovsdb-HwvtepSouthbound-Collection.json.postman_collection : Collection contains Restconf request for doing CRUD operations (hwvtep global node, physical switch, logical switch, physical locator, and physical port) on hwvtepsouthbound plugin running in standalone controller.
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.OutputPortValues;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
public final static long REG_VALUE_FROM_LOCAL = 0x1L;
public final static long REG_VALUE_FROM_REMOTE = 0x2L;
public static final Class<? extends NxmNxReg> REG_FIELD = NxmNxReg0.class;
+ public static final int ARP_OP_REQUEST = 0x1;
+ public static final int ARP_OP_REPLY = 0x2;
+
public static String getNodeName(long dpidLong) {
return OPENFLOW + ":" + dpidLong;
FlowBuilder flowBuilder = new FlowBuilder();
flowBuilder.setMatch(new MatchBuilder().build());
- String flowId = "DEFAULT_PIPELINE_FLOW_" + table;
- flowBuilder.setId(new FlowId(flowId));
- FlowKey key = new FlowKey(new FlowId(flowId));
- flowBuilder.setStrict(true);
- flowBuilder.setBarrier(false);
- flowBuilder.setTableId(table);
- flowBuilder.setKey(key);
- flowBuilder.setFlowName(flowId);
- flowBuilder.setHardTimeout(0);
- flowBuilder.setIdleTimeout(0);
- flowBuilder.setPriority(0);
+ String flowName = "DEFAULT_PIPELINE_FLOW_" + table;
+ return initFlowBuilder(flowBuilder, flowName, table)
+ .setPriority(0);
+ }
+
+ /**
+ * Sets up common defaults for the given flow builder: a flow identifier and key based on the given flow name,
+ * strict, no barrier, the given table identifier, no hard timeout and no idle timeout.
+ *
+ * @param flowBuilder The flow builder.
+ * @param flowName The flow name.
+ * @param table The table.
+ * @return The flow builder.
+ */
+ public static FlowBuilder initFlowBuilder(FlowBuilder flowBuilder, String flowName, short table) {
+ final FlowId flowId = new FlowId(flowName);
+ flowBuilder
+ .setId(flowId)
+ .setStrict(true)
+ .setBarrier(false)
+ .setTableId(table)
+ .setKey(new FlowKey(flowId))
+ .setFlowName(flowName)
+ .setHardTimeout(0)
+ .setIdleTimeout(0);
return flowBuilder;
}
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4Builder;
+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.types.rev131026.OutputPortValues;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
import java.math.BigInteger;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
public class InstructionUtils {
}
/**
- * Create LOCAL Reserved Port Instruction
+ * Create NORMAL Reserved Port Instruction (packet_in)
*
* @param nodeName Uri Prefix, containing nodeConnectorType and dpId (aka NodeId)
* @param ib Map InstructionBuilder without any instructions
}
/**
- * Create NORMAL Reserved Port Instruction (packet_in)
+ * Create LOCAL Reserved Port Instruction
*
* @param ib Map InstructionBuilder without any instructions
* @param dpidLong Long the datapath ID of a switch/node
return getInstructions(applyActionIns(dropAction()));
}
+ /**
+ * Extracts the existing instructions (if any) from the flow.
+ *
+ * @param flow The flow.
+ * @return The instructions in the flow (empty if none).
+ */
+ public static List<Instruction> extractExistingInstructions(Flow flow) {
+ if (flow != null) {
+ Instructions ins = flow.getInstructions();
+ if (ins != null) {
+ return ins.getInstruction();
+ }
+ }
+ return Collections.emptyList();
+ }
+
+ /**
+ * Configures the flow builder to have the single given instruction.
+ *
+ * @param flowBuilder The flow builder.
+ * @param instruction The instruction.
+ * @return The flow builder.
+ */
+ public static FlowBuilder setFlowBuilderInstruction(FlowBuilder flowBuilder, Instruction instruction) {
+ flowBuilder.setInstructions(
+ new InstructionsBuilder()
+ .setInstruction(Collections.singletonList(instruction))
+ .build());
+ return flowBuilder;
+ }
+
/**
* Get a list of Instructions containing Nicira extensions that can have
* additional OF/OXM instructions added to the returned Instruction list
public static final String UDP = "udp";
private static final int TCP_SYN = 0x0002;
public static final String ICMP = "icmp";
+ public static final short ALL_ICMP = -1;
/**
* Create Ingress Port Match dpidLong, inPort
return matchBuilder;
}
+ public static MatchBuilder createInPortReservedMatch(MatchBuilder matchBuilder, Long dpidLong, String inPort) {
+
+ NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + inPort);
+ LOG.debug("createInPortResrevedMatch() Node Connector ID is - Type=openflow: DPID={} inPort={} ",
+ dpidLong, inPort);
+ matchBuilder.setInPort(NodeConnectorId.getDefaultInstance(ncid.getValue()));
+ matchBuilder.setInPort(ncid);
+
+ return matchBuilder;
+ }
+
/**
* Create EtherType Match
*
// Build the ICMPv4 Match
Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
- icmpv4match.setIcmpv4Type(type);
- icmpv4match.setIcmpv4Code(code);
+ if (type != ALL_ICMP || code != ALL_ICMP) {
+ icmpv4match.setIcmpv4Type(type);
+ icmpv4match.setIcmpv4Code(code);
+ }
matchBuilder.setIcmpv4Match(icmpv4match.build());
return matchBuilder;
*/
public static MatchBuilder createArpDstIpv4Match(MatchBuilder matchBuilder, Ipv4Prefix dstip) {
ArpMatchBuilder arpDstMatch = new ArpMatchBuilder();
- arpDstMatch.setArpTargetTransportAddress(dstip);
+ arpDstMatch.setArpTargetTransportAddress(dstip)
+ .setArpOp(FlowUtils.ARP_OP_REQUEST);
matchBuilder.setLayer3Match(arpDstMatch.build());
return matchBuilder;