import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
-import java.net.InetAddress;
-import java.net.NetworkInterface;
-import java.net.UnknownHostException;
import java.util.ArrayList;
-import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.opendaylight.ovsdb.lib.notation.Version;
import org.opendaylight.ovsdb.openstack.netvirt.NetworkHandler;
import org.opendaylight.ovsdb.openstack.netvirt.api.BridgeConfigurationManager;
-import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.NetvirtProvidersProvider;
import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.PipelineOrchestrator;
import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
-import org.opendaylight.ovsdb.southbound.SouthboundMapper;
-import org.opendaylight.ovsdb.utils.config.ConfigProperties;
import org.opendaylight.ovsdb.utils.mdsal.openflow.FlowUtils;
import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
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.bridge.attributes.ControllerEntry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
-import org.opendaylight.yang.gen.v1.urn.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.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.ops4j.pax.exam.Configuration;
import org.ops4j.pax.exam.Option;
@ExamReactorStrategy(PerClass.class)
public class NetvirtIT extends AbstractMdsalTestBase {
private static final Logger LOG = LoggerFactory.getLogger(NetvirtIT.class);
- private static final int OVSDB_UPDATE_TIMEOUT = 1000;
private static DataBroker dataBroker = null;
private static String addressStr;
private static String portStr;
private static AtomicBoolean setup = new AtomicBoolean(false);
private static MdsalUtils mdsalUtils = null;
private static Southbound southbound = null;
+ private static PipelineOrchestrator pipelineOrchestrator = null;
private static SouthboundUtils southboundUtils;
private static NeutronUtils neutronUtils = new NeutronUtils();
private static final String NETVIRT_TOPOLOGY_ID = "netvirt:1";
southbound = (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
assertNotNull("southbound should not be null", southbound);
southboundUtils = new SouthboundUtils(mdsalUtils);
+ pipelineOrchestrator =
+ (PipelineOrchestrator) ServiceHelper.getGlobalInstance(PipelineOrchestrator.class, this);
+ assertNotNull("pipelineOrchestrator should not be null", pipelineOrchestrator);
setup.set(true);
}
return true;
}
+ // This is an extra test for local testing and testNetVirt covers this is more detail
+ @Ignore
@Test
public void testAddDeleteOvsdbNode() throws InterruptedException {
LOG.info("testAddDeleteOvsdbNode enter");
ConnectionInfo connectionInfo = SouthboundUtils.getConnectionInfo(addressStr, portStr);
- connectOvsdbNode(connectionInfo);
+ Node ovsdbNode = connectOvsdbNode(connectionInfo);
+ assertNotNull("connection failed", ovsdbNode);
+ LOG.info("testNetVirt: should be connected: {}", ovsdbNode.getNodeId());
assertTrue("Controller " + SouthboundUtils.connectionInfoToString(connectionInfo)
+ " is not connected", isControllerConnected(connectionInfo));
LOG.info("testAddDeleteOvsdbNode exit");
}
+ // TODO add tests for when L3 is enabled and check for br-ex
+
+ // This is an extra test for local testing and testNetVirt covers this is more detail
+ @Ignore
+ @Test
+ public void testAddDeleteOvsdbNodeWithTableOffset() throws InterruptedException {
+ LOG.info("testAddDeleteOvsdbNodeWithTableOffset enter");
+ NetvirtProvidersProvider.setTableOffset((short)1);
+ ConnectionInfo connectionInfo = SouthboundUtils.getConnectionInfo(addressStr, portStr);
+ Node ovsdbNode = connectOvsdbNode(connectionInfo);
+ assertNotNull("connection failed", ovsdbNode);
+ LOG.info("testNetVirt: should be connected: {}", ovsdbNode.getNodeId());
+
+ assertTrue("Controller " + SouthboundUtils.connectionInfoToString(connectionInfo)
+ + " is not connected", isControllerConnected(connectionInfo));
+
+ // Verify the pipeline flows were installed
+ Node bridgeNode = southbound.getBridgeNode(ovsdbNode, NetvirtITConstants.INTEGRATION_BRIDGE_NAME);
+ assertNotNull("bridge " + NetvirtITConstants.INTEGRATION_BRIDGE_NAME + " was not found", bridgeNode);
+ long datapathId = southbound.getDataPathId(bridgeNode);
+ String datapathIdString = southbound.getDatapathId(bridgeNode);
+ LOG.info("testNetVirt: bridgeNode: {}, datapathId: {} - {}", bridgeNode, datapathIdString, datapathId);
+ assertNotEquals("datapathId was not found", datapathId, 0);
+
+ List<Service> staticPipeline = pipelineOrchestrator.getStaticPipeline();
+ List<Service> staticPipelineFound = Lists.newArrayList();
+ for (Service service : pipelineOrchestrator.getServiceRegistry().keySet()) {
+ if (staticPipeline.contains(service)) {
+ staticPipelineFound.add(service);
+ }
+ String flowId = "DEFAULT_PIPELINE_FLOW_" + pipelineOrchestrator.getTable(service);
+ verifyFlow(datapathId, flowId, service);
+ }
+ assertEquals("did not find all expected flows in static pipeline",
+ staticPipeline.size(), staticPipelineFound.size());
+
+ String flowId = "TableOffset_" + pipelineOrchestrator.getTable(Service.CLASSIFIER);
+ verifyFlow(datapathId, flowId, Service.CLASSIFIER.getTable());
+
+ Assert.assertTrue(southboundUtils.deleteBridge(connectionInfo, NetvirtITConstants.INTEGRATION_BRIDGE_NAME));
+ Thread.sleep(1000);
+ Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
+ LOG.info("testAddDeleteOvsdbNodeWithTableOffset exit");
+ }
+
private boolean isControllerConnected(ConnectionInfo connectionInfo) throws InterruptedException {
LOG.info("isControllerConnected enter");
Boolean connected = false;
BridgeConfigurationManager bridgeConfigurationManager =
(BridgeConfigurationManager) ServiceHelper.getGlobalInstance(BridgeConfigurationManager.class, this);
- assertNotNull("Could not find PipelineOrchestrator Service", bridgeConfigurationManager);
+ assertNotNull("Could not find BridgeConfigurationManager Service", bridgeConfigurationManager);
String controllerTarget = bridgeConfigurationManager.getControllersFromOvsdbNode(ovsdbNode).get(0);
Assert.assertNotNull("Failed to get controller target", controllerTarget);
LOG.info("testNetVirt: starting test");
ConnectionInfo connectionInfo = SouthboundUtils.getConnectionInfo(addressStr, portStr);
Node ovsdbNode = connectOvsdbNode(connectionInfo);
- LOG.info("testNetVirt: should be connected");
+ assertNotNull("connection failed", ovsdbNode);
+ LOG.info("testNetVirt: should be connected: {}", ovsdbNode.getNodeId());
//TODO use controller value rather that ovsdb connectionInfo or change log
assertTrue("Controller " + SouthboundUtils.connectionInfoToString(connectionInfo)
+ " is not connected", isControllerConnected(connectionInfo));
// 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);
+ String datapathIdString = southbound.getDatapathId(bridgeNode);
+ LOG.info("testNetVirt: bridgeNode: {}, datapathId: {} - {}", bridgeNode, datapathIdString, datapathId);
assertNotEquals("datapathId was not found", datapathId, 0);
List<Service> staticPipeline = pipelineOrchestrator.getStaticPipeline();
if (staticPipeline.contains(service)) {
staticPipelineFound.add(service);
}
- String flowId = "DEFAULT_PIPELINE_FLOW_" + service.getTable();
- verifyFlow(datapathId, flowId, service.getTable());
+ String flowId = "DEFAULT_PIPELINE_FLOW_" + pipelineOrchestrator.getTable(service);
+ verifyFlow(datapathId, flowId, service);
}
assertEquals("did not find all expected flows in static pipeline",
staticPipeline.size(), staticPipelineFound.size());
OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
southbound.getTerminationPointOfBridge(bridgeNode, NetvirtITConstants.PORT_NAME);
Assert.assertNotNull("Did not find " + NetvirtITConstants.PORT_NAME, ovsdbTerminationPointAugmentation);
- Thread.sleep(1000);
Assert.assertTrue(southboundUtils.deleteBridge(connectionInfo, NetvirtITConstants.INTEGRATION_BRIDGE_NAME));
Thread.sleep(1000);
Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
final String dhcpPortId ="521e29d6-67b8-4b3c-8633-027d21195115";
ConnectionInfo connectionInfo = SouthboundUtils.getConnectionInfo(addressStr, portStr);
- assertNotNull("connection failed", southboundUtils.connectOvsdbNode(connectionInfo));
Node ovsdbNode = connectOvsdbNode(connectionInfo);
- assertNotNull("node is not connected", ovsdbNode);
+ assertNotNull("connection failed", ovsdbNode);
+ LOG.info("testNetVirtFixedSG: should be connected: {}", ovsdbNode.getNodeId());
// Verify the minimum version required for this test
OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
Node bridgeNode = southbound.getBridgeNode(ovsdbNode, NetvirtITConstants.INTEGRATION_BRIDGE_NAME);
assertNotNull("bridge " + NetvirtITConstants.INTEGRATION_BRIDGE_NAME + " was not found", bridgeNode);
long datapathId = southbound.getDataPathId(bridgeNode);
+ String datapathIdString = southbound.getDatapathId(bridgeNode);
+ LOG.info("testNetVirtFixedSG: bridgeNode: {}, datapathId: {} - {}", bridgeNode, datapathIdString, datapathId);
assertNotEquals("datapathId was not found", datapathId, 0);
NeutronNetwork nn = neutronUtils.createNeutronNetwork(networkId, tenantId,
Thread.sleep(1000);
String flowId = "Egress_DHCP_Client" + "_Permit_";
- verifyFlow(datapathId, flowId, Service.EGRESS_ACL.getTable());
+ verifyFlow(datapathId, flowId, Service.EGRESS_ACL);
testDefaultSG(nport, datapathId, nn, tenantId, portId);
Thread.sleep(1000);
Thread.sleep(10000);
String flowId = "Egress_IP" + nn.getProviderSegmentationID() + "_" + nport.getMacAddress() + "_Permit_";
- verifyFlow(datapathId, flowId, Service.EGRESS_ACL.getTable());
+ verifyFlow(datapathId, flowId, Service.EGRESS_ACL);
flowId = "Ingress_IP" + nn.getProviderSegmentationID() + "_" + nport.getMacAddress() + "_Permit_";
- verifyFlow(datapathId, flowId, Service.INGRESS_ACL.getTable());
+ verifyFlow(datapathId, flowId, Service.INGRESS_ACL);
}
private Flow getFlow (
Flow flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.CONFIGURATION);
assertNotNull("Could not find flow in config: " + flowBuilder.build() + "--" + nodeBuilder.build(), flow);
flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.OPERATIONAL);
- assertNotNull("Could not find flow in operational: " + flowBuilder.build() + "--" + nodeBuilder.build(), flow);
+ assertNotNull("Could not find flow in operational: " + flowBuilder.build() + "--" + nodeBuilder.build(),
+ flow);
+ }
+
+ private void verifyFlow(long datapathId, String flowId, Service service) throws InterruptedException {
+ verifyFlow(datapathId, flowId, pipelineOrchestrator.getTable(service));
}
}
<module>
<type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:netvirt:providers:impl">prefix:netvirt-providers-impl</type>
<name>netvirt-providers-default</name>
+ <table-offset>0</table-offset>
<broker>
<type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
<name>binding-osgi-broker</name>
package org.opendaylight.ovsdb.openstack.netvirt.providers;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
import org.opendaylight.ovsdb.openstack.netvirt.api.ArpProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.List;
-
public class ConfigActivator implements BundleActivator {
private static final Logger LOG = LoggerFactory.getLogger(ConfigActivator.class);
private List<ServiceRegistration<?>> registrations = new ArrayList<>();
public void start(BundleContext context) throws Exception {
LOG.info("ConfigActivator start:");
+ NetvirtProvidersConfigImpl netvirtProvidersConfig =
+ new NetvirtProvidersConfigImpl(providerContext.getSALService(DataBroker.class),
+ NetvirtProvidersProvider.getTableOffset());
+ registerService(context,
+ new String[] {NetvirtProvidersConfigImpl.class.getName()},
+ null, netvirtProvidersConfig);
+
PipelineOrchestratorImpl pipelineOrchestrator = new PipelineOrchestratorImpl();
registerService(context,
new String[] {PipelineOrchestrator.class.getName(),NodeCacheListener.class.getName()},
gatewayMacResolverService, Service.GATEWAY_RESOLVER);
getNotificationProviderService().registerNotificationListener(gatewayMacResolverService);
-
+ netvirtProvidersConfig.setDependencies(context, null);
pipelineOrchestrator.setDependencies(context, null);
outboundNatService.setDependencies(context, null);
egressAclService.setDependencies(context, null);
--- /dev/null
+/*
+ * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.ovsdb.openstack.netvirt.providers;
+
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
+import org.opendaylight.ovsdb.openstack.netvirt.api.OvsdbInventoryListener;
+import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.providers.config.rev160109.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NetvirtProvidersConfigImpl implements AutoCloseable, ConfigInterface, DataChangeListener {
+ private static final Logger LOG = LoggerFactory.getLogger(NetvirtProvidersConfigImpl.class);
+ private final DataBroker dataBroker;
+ private final ListenerRegistration<DataChangeListener> registration;
+ private final ExecutorService executorService = Executors.newFixedThreadPool(1);
+ private final MdsalUtils mdsalUtils;
+
+ public NetvirtProvidersConfigImpl(final DataBroker dataBroker, final short tableOffset) {
+ this.dataBroker = dataBroker;
+ mdsalUtils = new MdsalUtils(dataBroker);
+
+ InstanceIdentifier<NetvirtProvidersConfig> path =
+ InstanceIdentifier.builder(NetvirtProvidersConfig.class).build();
+ registration = dataBroker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, path, this,
+ AsyncDataBroker.DataChangeScope.SUBTREE);
+
+ NetvirtProvidersConfigBuilder netvirtProvidersConfigBuilder = new NetvirtProvidersConfigBuilder();
+ NetvirtProvidersConfig netvirtProvidersConfig =
+ mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, path);
+ if (netvirtProvidersConfig != null) {
+ netvirtProvidersConfigBuilder = new NetvirtProvidersConfigBuilder(netvirtProvidersConfig);
+ }
+ if (netvirtProvidersConfigBuilder.getTableOffset() == null) {
+ netvirtProvidersConfigBuilder.setTableOffset(tableOffset);
+ }
+ boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, path,
+ netvirtProvidersConfigBuilder.build());
+
+ LOG.info("NetvirtProvidersConfigImpl: dataBroker= {}, registration= {}, tableOffset= {}, result= {}",
+ dataBroker, registration, tableOffset, result);
+ }
+
+ @Override
+ public void close() throws Exception {
+ registration.close();
+ executorService.shutdown();
+ }
+
+ @Override
+ public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> asyncDataChangeEvent) {
+ executorService.submit(new Runnable() {
+
+ @Override
+ public void run() {
+ LOG.info("onDataChanged: {}", asyncDataChangeEvent);
+ processConfigCreate(asyncDataChangeEvent);
+ processConfigUpdate(asyncDataChangeEvent);
+ }
+ });
+ }
+
+ private void processConfigCreate(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes) {
+ for (Map.Entry<InstanceIdentifier<?>, DataObject> entry : changes.getCreatedData().entrySet()) {
+ if (entry.getValue() instanceof NetvirtProvidersConfig) {
+ NetvirtProvidersConfig netvirtProvidersConfig = (NetvirtProvidersConfig) entry.getValue();
+ applyConfig(netvirtProvidersConfig);
+ }
+ }
+ }
+
+ private void processConfigUpdate(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes) {
+ for (Map.Entry<InstanceIdentifier<?>, DataObject> entry : changes.getUpdatedData().entrySet()) {
+ if (entry.getValue() instanceof NetvirtProvidersConfig) {
+ LOG.info("processConfigUpdate: {}", entry);
+ NetvirtProvidersConfig netvirtProvidersConfig = (NetvirtProvidersConfig) entry.getValue();
+ applyConfig(netvirtProvidersConfig);
+ }
+ }
+ }
+
+ private void applyConfig(NetvirtProvidersConfig netvirtProvidersConfig) {
+ LOG.info("processConfigUpdate: {}", netvirtProvidersConfig);
+ if (netvirtProvidersConfig.getTableOffset() != null) {
+ NetvirtProvidersProvider.setTableOffset(netvirtProvidersConfig.getTableOffset());
+ }
+ }
+
+ @Override
+ public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
+
+ }
+
+ @Override
+ public void setDependencies(Object impl) {
+
+ }
+}
import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableId;
import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static EntityOwnershipService entityOwnershipService;
private ProviderEntityListener providerEntityListener = null;
private static AtomicBoolean hasProviderEntityOwnership = new AtomicBoolean(false);
+ private static short tableOffset;
+ private NetvirtProvidersConfigImpl netvirtProvidersConfig = null;
- public NetvirtProvidersProvider(BundleContext bundleContext, EntityOwnershipService eos) {
+ public NetvirtProvidersProvider(BundleContext bundleContext, EntityOwnershipService eos, short tableOffset) {
LOG.info("NetvirtProvidersProvider: bundleContext: {}", bundleContext);
this.bundleContext = bundleContext;
- entityOwnershipService = eos;
+ entityOwnershipService = eos;
+ setTableOffset(tableOffset);
}
public static DataBroker getDataBroker() {
return hasProviderEntityOwnership.get();
}
+ public static void setTableOffset(short tableOffset) {
+ try {
+ new TableId((short) (tableOffset + Service.L2_FORWARDING.getTable()));
+ } catch (IllegalArgumentException e) {
+ LOG.warn("Invalid table offset: {}", tableOffset, e);
+ return;
+ }
+
+ LOG.info("setTableOffset: changing from {} to {}",
+ NetvirtProvidersProvider.tableOffset, tableOffset);
+ NetvirtProvidersProvider.tableOffset = tableOffset;
+ }
+
+ public static short getTableOffset() {
+ return tableOffset;
+ }
+
@Override
public void close() throws Exception {
LOG.info("NetvirtProvidersProvider closed");
return bridgeName != null && Constants.INTEGRATION_BRIDGE.equals(bridgeName);
}
+ /**
+ * Return the offset adjusted table for this {@link Service}
+ * @return The table id
+ */
public short getTable() {
- return service.getTable();
+ return (short)(orchestrator.getTableOffset() + service.getTable());
+ }
+
+ /**
+ * Return the offset adjusted table for the given {@link Service}
+ * @param service Identifies the openflow {@link Service}
+ * @return The table id
+ */
+ public short getTable(Service service) {
+ return (short)(orchestrator.getTableOffset() + service.getTable());
}
public Service getService() {
protected final InstructionBuilder getMutablePipelineInstructionBuilder() {
Service nextService = orchestrator.getNextServiceInPipeline(service);
if (nextService != null) {
- return InstructionUtils.createGotoTableInstructions(new InstructionBuilder(), nextService.getTable());
+ return InstructionUtils.createGotoTableInstructions(new InstructionBuilder(),
+ orchestrator.getTable(nextService));
} else {
return InstructionUtils.createDropInstructions(new InstructionBuilder());
}
protected void writeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
if (NetvirtProvidersProvider.isMasterProviderInstance()) {
- LOG.debug("writeFlow 3: flowBuilder: {}, nodeBuilder: {}",
+ LOG.debug("writeFlow: flowBuilder: {}, nodeBuilder: {}",
flowBuilder.build(), nodeBuilder.build());
WriteTransaction modification = dataBroker.newWriteOnlyTransaction();
- LOG.debug("writeFlow: about to put nodePath for Flow {}, nodePath: {}",
- flowBuilder.getFlowName(), createNodePath(nodeBuilder));
modification.put(LogicalDatastoreType.CONFIGURATION, createNodePath(nodeBuilder),
nodeBuilder.build(), true /*createMissingParents*/);
- LOG.debug("writeFlow: about to put Flow {}", flowBuilder.getFlowName());
modification.put(LogicalDatastoreType.CONFIGURATION, createFlowPath(flowBuilder, nodeBuilder),
flowBuilder.build(), true /*createMissingParents*/);
- LOG.debug("writeFlow: about to submit Flow {}", flowBuilder.getFlowName());
CheckedFuture<Void, TransactionCommitFailedException> commitFuture = modification.submit();
- LOG.debug("writeFlow: checking status of Flow {}", flowBuilder.getFlowName());
try {
commitFuture.checkedGet(); // TODO: Make it async (See bug 1362)
LOG.debug("Transaction success for write of Flow {}", flowBuilder.getFlowName());
// Add InstructionsBuilder to FlowBuilder
flowBuilder.setInstructions(isb.build());
- String flowId = "DEFAULT_PIPELINE_FLOW_"+service.getTable();
+ String flowId = "DEFAULT_PIPELINE_FLOW_" + getTable();
flowBuilder.setId(new FlowId(flowId));
FlowKey key = new FlowKey(new FlowId(flowId));
flowBuilder.setMatch(matchBuilder.build());
flowBuilder.setPriority(0);
flowBuilder.setBarrier(false);
- flowBuilder.setTableId(service.getTable());
+ flowBuilder.setTableId(getTable());
flowBuilder.setKey(key);
flowBuilder.setFlowName(flowId);
flowBuilder.setHardTimeout(0);
writeLLDPRule(dpid);
+ if (bridgeName.equals(configurationService.getIntegrationBridgeName()) &&
+ NetvirtProvidersProvider.getTableOffset() != 0) {
+ classifierProvider.programGotoTable(dpid,true);
+ }
+
if (bridgeName.equals(configurationService.getExternalBridgeName())) {
writeNormalRule(dpid);
}
NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
FlowBuilder flowBuilder = new FlowBuilder();
String flowName = "NORMAL";
- FlowUtils.initFlowBuilder(flowBuilder, flowName, (short)0).setPriority(0);
+ FlowUtils.initFlowBuilder(flowBuilder, flowName, Service.CLASSIFIER.getTable()).setPriority(0);
MatchBuilder matchBuilder = new MatchBuilder();
flowBuilder.setMatch(matchBuilder.build());
Service getNextServiceInPipeline(Service service);
AbstractServiceInstance getServiceInstance(Service service);
Map<Service, AbstractServiceInstance> getServiceRegistry();
+ short getTableOffset();
+ short getTable(Service service);
List<Service> getStaticPipeline();
void enqueue(Node node);
void registerService(final ServiceReference ref, AbstractServiceInstance serviceInstance);
import org.opendaylight.ovsdb.openstack.netvirt.api.NodeCacheManager;
import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
import org.opendaylight.ovsdb.openstack.netvirt.providers.ConfigInterface;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.NetvirtProvidersProvider;
import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
import org.osgi.framework.BundleContext;
public class PipelineOrchestratorImpl implements ConfigInterface, NodeCacheListener, PipelineOrchestrator {
private static final Logger LOG = LoggerFactory.getLogger(PipelineOrchestratorImpl.class);
+ /**
+ * Return the current table offset
+ * @return The table offset
+ */
+ @Override
+ public short getTableOffset() {
+ return NetvirtProvidersProvider.getTableOffset();
+ }
+
+ /**
+ * Return the offset adjusted table for the given {@link Service}
+ * @param service Identifies the openflow {@link Service}
+ * @return The table id
+ */
+ @Override
+ public short getTable(Service service) {
+ return (short)(getTableOffset() + service.getTable());
+ }
+
public List<Service> getStaticPipeline() {
return staticPipeline;
}
while (true) {
Node node = queue.take();
LOG.info(">>>>> dequeue: {}", node);
- for (Service service : staticPipeline) {
- AbstractServiceInstance serviceInstance = getServiceInstance(service);
- if (serviceInstance != null && southbound.getBridge(node) != null) {
- serviceInstance.programDefaultPipelineRule(node);
+ if (southbound.getBridge(node) != null) {
+ for (Service service : staticPipeline) {
+ AbstractServiceInstance serviceInstance = getServiceInstance(service);
+ if (serviceInstance != null) {
+ serviceInstance.programDefaultPipelineRule(node);
+ }
}
+ // TODO: might need a flow to go from table 0 to the pipeline
}
}
} catch (Exception e) {
NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
FlowBuilder flowBuilder = new FlowBuilder();
String flowName = "LLDP";
- FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable());
+ FlowUtils.initFlowBuilder(flowBuilder, flowName, Service.CLASSIFIER.getTable());
MatchBuilder matchBuilder = new MatchBuilder();
MatchUtils.createEtherTypeMatch(matchBuilder, new EtherType(0x88CCL));
writeFlow(flowBuilder, nodeBuilder);
}
+ @Override
+ public void programGotoTable(Long dpidLong, boolean write) {
+ NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
+ FlowBuilder flowBuilder = new FlowBuilder();
+ String flowName = "TableOffset_" + getTable();
+ FlowUtils.initFlowBuilder(flowBuilder, flowName, Service.CLASSIFIER.getTable())
+ .setPriority(0);
+
+ MatchBuilder matchBuilder = new MatchBuilder();
+ flowBuilder.setMatch(matchBuilder.build());
+
+ if (write) {
+ InstructionsBuilder isb = new InstructionsBuilder();
+ List<Instruction> instructions = Lists.newArrayList();
+ InstructionBuilder ib =
+ InstructionUtils.createGotoTableInstructions(new InstructionBuilder(), getTable());
+ 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);
+ }
+ }
+
@Override
public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
super.setDependencies(bundleContext.getServiceReference(ClassifierProvider.class.getName()), this);
implements ConfigInterface, GatewayMacResolver,PacketProcessingListener {
private static final Logger LOG = LoggerFactory.getLogger(GatewayMacResolverService.class);
- private static final short TABLE_FOR_ARP_FLOW = 0;
private static final String ARP_REPLY_TO_CONTROLLER_FLOW_NAME = "GatewayArpReplyRouter";
private static final int ARP_REPLY_TO_CONTROLLER_FLOW_PRIORITY = 10000;
private static final Instruction SEND_TO_CONTROLLER_INSTRUCTION;
private Flow createArpReplyToControllerFlow(final ArpMessageAddress senderAddress, final Ipv4Address ipForRequestedMac) {
checkNotNull(senderAddress);
checkNotNull(ipForRequestedMac);
- FlowBuilder arpFlow = new FlowBuilder().setTableId(TABLE_FOR_ARP_FLOW)
+ FlowBuilder arpFlow = new FlowBuilder().setTableId(Service.CLASSIFIER.getTable())
.setFlowName(ARP_REPLY_TO_CONTROLLER_FLOW_NAME)
.setPriority(ARP_REPLY_TO_CONTROLLER_FLOW_PRIORITY)
.setBufferId(OFConstants.OFP_NO_BUFFER)
@Override
public java.lang.AutoCloseable createInstance() {
- NetvirtProvidersProvider provider = new NetvirtProvidersProvider(bundleContext, getClusteringEntityOwnershipServiceDependency());
+ NetvirtProvidersProvider provider = new NetvirtProvidersProvider(bundleContext,
+ getClusteringEntityOwnershipServiceDependency(), getTableOffset());
BindingAwareBroker localBroker = getBrokerDependency();
localBroker.registerProvider(provider);
return provider;
--- /dev/null
+module netvirt-providers-config {
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:netvirt:providers:config";
+ prefix "netvirt-providers-config";
+
+ revision "2016-01-09" {
+ description "Initial revision of the netvirt providers config";
+ }
+
+ container netvirt-providers-config {
+ description "Configuration for NetvirtProviders";
+
+ config true;
+
+ leaf table-offset {
+ description "The table-offset is used to set the starting table for the netvirt pipeline";
+ type uint8;
+ }
+ }
+}
}
}
}
+
container clustering-entity-ownership-service {
uses config:service-ref {
refine type {
}
}
}
+
+ leaf table-offset {
+ description "The table-offset is used to set the starting table for the netvirt pipeline";
+ type uint8;
+ }
}
}
}
--- /dev/null
+/*
+ * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.openstack.netvirt.providers;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.PipelineOrchestratorImpl;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
+import org.osgi.framework.BundleContext;
+
+/**
+ * Unit tests for {@link NetvirtProvidersProvider}
+ */
+public class NetvirtProvidersProviderTest {
+
+ /**
+ * Test for {@link NetvirtProvidersProvider#getTableOffset()}
+ */
+ @Test
+ public void testGetTableOffset() {
+ short tableOffset = 10;
+ NetvirtProvidersProvider netvirtProvidersProvider = new NetvirtProvidersProvider(null, null, tableOffset);
+ assertEquals("Table offset was not set", tableOffset, NetvirtProvidersProvider.getTableOffset());
+ }
+
+ /**
+ * Test for method {@link NetvirtProvidersProvider#setTableOffset(short)}
+ */
+ @Test
+ public void testSetTableOffset() {
+ // verify a good value can be set
+ short tableOffset = 0;
+ NetvirtProvidersProvider netvirtProvidersProvider = new NetvirtProvidersProvider(null, null, tableOffset);
+
+ tableOffset = 10;
+ NetvirtProvidersProvider.setTableOffset(tableOffset);
+ assertEquals("tableOffset was not set", tableOffset, NetvirtProvidersProvider.getTableOffset());
+ }
+
+ /**
+ * Negative test for method {@link NetvirtProvidersProvider#setTableOffset(short)}
+ */
+ @Test
+ public void testTableOffsetNegative() {
+ // verify an out of range value is not set
+ short tableOffset = 0;
+ NetvirtProvidersProvider netvirtProvidersProvider = new NetvirtProvidersProvider(null, null, tableOffset);
+
+ short tableOffsetBad = (short)(256 - Service.L2_FORWARDING.getTable());
+ NetvirtProvidersProvider.setTableOffset(tableOffsetBad);
+ assertEquals("tableOffset should not be set", 0, NetvirtProvidersProvider.getTableOffset());
+ }
+}
private final String NODE_ID = Constants.INTEGRATION_BRIDGE + ":" + ID;
/**
- * Test method {@link AbstractServiceInstance#isBridgeInPipeline(String)}
+ * Test method {@link AbstractServiceInstance#isBridgeInPipeline(Node)}
*/
@Test
public void testIsBridgeInPipeline() {
@Test
public void testGetTable() {
abstractServiceInstance.setService(service);
- assertEquals("Error, getTable() did not return the correct value", 70, abstractServiceInstance.getTable());
+ assertEquals("Error, getTable() did not return the correct value",
+ service.getTable(), abstractServiceInstance.getTable());
+
+ when(orchestrator.getTableOffset()).thenReturn(Service.DIRECTOR.getTable());
+ assertEquals("Error, getTable() did not return the correct value",
+ (short)(Service.DIRECTOR.getTable() + service.getTable()), abstractServiceInstance.getTable());
+ }
+
+ /**
+ * Test method {@link AbstractServiceInstance@getTable(Service}
+ */
+ @Test
+ public void testGetTableWithService() {
+ when(orchestrator.getTableOffset()).thenReturn((short)0);
+ abstractServiceInstance.setService(service);
+ assertEquals("Error, getTables(service) did not return the correct value",
+ Service.L2_FORWARDING.getTable(), abstractServiceInstance.getTable(Service.L2_FORWARDING));
}
@Test
}
/**
- * Test method {@link AbstractServiceInstance#programDefaultPipelineRule(String)}
+ * Test method {@link AbstractServiceInstance#programDefaultPipelineRule(Node)}
*/
@Test
public void testProgramDefaultPipelineRule() {
@Mock private ExecutorService eventHandler;
@Mock private Southbound southbound;
+ /**
+ * Test for method {@link PipelineOrchestratorImpl#getTableOffset()}
+ */
+ @Test
+ public void testGetTableOffset() {
+ short tableOffset = 0;
+ assertEquals("tableOffset was not set", tableOffset, orchestrator.getTableOffset());
+ }
+
+ /**
+ * Test for {@link PipelineOrchestratorImpl#getTable(Service)}
+ */
+ @Test
+ public void testGetTableOffsetWithService() {
+ assertEquals("tableOffset was not set", Service.CLASSIFIER.getTable(),
+ orchestrator.getTable(Service.CLASSIFIER));
+ }
+
/***
* Registers a mock service and verifies the registration by asking the
* pipeline orchestrator to return the associated service from its internal
/**
* Test method
- * {@link PipelineOrchestratorImplr#getNextServiceInPipeline(Service)}
+ * {@link PipelineOrchestratorImpl#getNextServiceInPipeline(Service)}
*/
@Test
public void testGetNextServiceInPipeline() {
public class SfcClassifierService extends AbstractServiceInstance implements ConfigInterface, ISfcClassifierService {
private static final Logger LOG = LoggerFactory.getLogger(SfcClassifierService.class);
- private static final short TABLE_0 = 0;
private static final short UDP_SHORT = 17;
static int cookieIndex = 0;
flowBuilder.setId(new FlowId(flowId));
FlowKey key = new FlowKey(new FlowId(flowId));
flowBuilder.setBarrier(true);
- flowBuilder.setTableId(TABLE_0);
+ flowBuilder.setTableId(getTable(Service.CLASSIFIER));
flowBuilder.setKey(key);
flowBuilder.setFlowName(flowId);
flowBuilder.setHardTimeout(0);
flowBuilder.setId(new FlowId(flowId));
FlowKey key = new FlowKey(new FlowId(flowId));
flowBuilder.setBarrier(true);
- flowBuilder.setTableId(TABLE_0);
+ flowBuilder.setTableId(getTable(Service.CLASSIFIER));
flowBuilder.setKey(key);
flowBuilder.setFlowName(flowId);
flowBuilder.setHardTimeout(0);
flowBuilder.setId(new FlowId(flowId));
FlowKey key = new FlowKey(new FlowId(flowId));
flowBuilder.setBarrier(true);
- flowBuilder.setTableId(TABLE_0);
+ flowBuilder.setTableId(getTable(Service.CLASSIFIER));
flowBuilder.setKey(key);
flowBuilder.setFlowName(flowId);
flowBuilder.setHardTimeout(0);
ab.setKey(new ActionKey(actionList.size()));
actionList.add(ab.build());
- ab.setAction(ActionUtils.nxResubmitAction((int)sfOfPort, TABLE_0));
+ ab.setAction(ActionUtils.nxResubmitAction((int)sfOfPort, Service.CLASSIFIER.getTable()));
ab.setOrder(actionList.size());
ab.setKey(new ActionKey(actionList.size()));
actionList.add(ab.build());
NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
FlowBuilder flowBuilder = new FlowBuilder();
String flowName = "sfcEgressClassBypass_" + nsp + "_" + + nsi + "_" + sfOfPort;
- initFlowBuilder(flowBuilder, flowName, TABLE_0, FlowID.FLOW_EGRESSCLASSBYPASS).setPriority(40000);
+ initFlowBuilder(flowBuilder, flowName, Service.CLASSIFIER.getTable(),
+ FlowID.FLOW_EGRESSCLASSBYPASS).setPriority(40000);
MatchBuilder matchBuilder = new MatchBuilder();
MatchUtils.createInPortMatch(matchBuilder, dataPathId, sfOfPort);
NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
FlowBuilder flowBuilder = new FlowBuilder();
String flowName = "sfIngress_" + dstPort + "_" + ipAddress;
- initFlowBuilder(flowBuilder, flowName, TABLE_0, FlowID.FLOW_SFINGRESS);
+ initFlowBuilder(flowBuilder, flowName, Service.CLASSIFIER.getTable(), FlowID.FLOW_SFINGRESS);
MatchBuilder matchBuilder = new MatchBuilder();
MatchUtils.createIpProtocolMatch(matchBuilder, UDP_SHORT);
NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
FlowBuilder flowBuilder = new FlowBuilder();
String flowName = "ArpResponder_" + ipAddress;
- initFlowBuilder(flowBuilder, flowName, TABLE_0, FlowID.FLOW_SFARP).setPriority(1024);
+ initFlowBuilder(flowBuilder, flowName, Service.CLASSIFIER.getTable(), FlowID.FLOW_SFARP).setPriority(1024);
MacAddress macAddress = new MacAddress(macAddressStr);
package org.opendaylight.ovsdb.openstack.netvirt.sfc;
-import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
import java.io.IOException;
-import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.mdsal.it.base.AbstractMdsalTestBase;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.ovsdb.openstack.netvirt.api.BridgeConfigurationManager;
import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.PipelineOrchestrator;
import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
import org.opendaylight.ovsdb.openstack.netvirt.sfc.standalone.openflow13.SfcClassifier;
import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.AclUtils;
import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.ServiceFunctionUtils;
import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.SfcUtils;
import org.opendaylight.ovsdb.southbound.SouthboundConstants;
-import org.opendaylight.ovsdb.southbound.SouthboundUtil;
import org.opendaylight.ovsdb.utils.mdsal.openflow.FlowUtils;
-import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
import org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.AccessListEntriesBuilder;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.AceBuilder;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.ActionsBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.Matches;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.MatchesBuilder;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
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.FlowId;
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.MatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.Classifiers;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.ClassifiersBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.ClassifierBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev150105.Sfc;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev150105.SfcBuilder;
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.OvsdbTerminationPointAugmentation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.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.node.TerminationPoint;
import org.opendaylight.yangtools.concepts.Builder;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
private static String addressStr;
private static String portStr;
private static String connectionType;
+ private static String controllerStr;
private static boolean ovsdb_wait = false;
+ private static String userSpaceEnabled = "no";
+ private static PipelineOrchestrator pipelineOrchestrator;
private static Southbound southbound;
private static DataBroker dataBroker;
public static final String CONTROLLER_IPADDRESS = "ovsdb.controller.address";
public static final String CONNECTION_TYPE_ACTIVE = "active";
public static final String CONNECTION_TYPE_PASSIVE = "passive";
public static final String DEFAULT_SERVER_PORT = "6640";
+ public static final String USERSPACE_ENABLED = "ovsdb.userspace.enabled";
public static final String INTEGRATION_BRIDGE_NAME = "br-int";
private static final String NETVIRT_TOPOLOGY_ID = "netvirt:1";
private static final String OVSDB_TRACE = "ovsdb.trace";
private static final String SFCPATH = "SFC-Path";
private static final String SFCSF1NAME = "firewall-abstract";
private static final SftType SFCSF1TYPE = new SftType("firewall");
- private static final int GPEPORT = 6633;
+ private static final int GPEUDPPORT = 6633;
@Override
public String getModuleName() {
public Option[] getPropertiesOptions() {
return new Option[] {
propagateSystemProperties(SERVER_IPADDRESS, SERVER_PORT, CONNECTION_TYPE,
- CONTROLLER_IPADDRESS, OVSDB_TRACE, OVSDB_WAIT),
+ CONTROLLER_IPADDRESS, OVSDB_TRACE, OVSDB_WAIT, USERSPACE_ENABLED),
};
}
editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
"log4j.logger.org.opendaylight.ovsdb.openstack.netvirt.sfc",
LogLevel.TRACE.name()),
- //editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
- // "log4j.logger.org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13",
- // LogLevel.TRACE.name()),
+ editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
+ "log4j.logger.org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13",
+ LogLevel.TRACE.name()),
editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
"log4j.logger.org.opendaylight.sfc",
LogLevel.TRACE.name()),
addressStr = props.getProperty(SERVER_IPADDRESS);
portStr = props.getProperty(SERVER_PORT, DEFAULT_SERVER_PORT);
connectionType = props.getProperty(CONNECTION_TYPE, "active");
- LOG.info("setUp: Using the following properties: mode= {}, ip:port= {}:{}",
- connectionType, addressStr, portStr);
+ controllerStr = props.getProperty(CONTROLLER_IPADDRESS, "0.0.0.0");
+ userSpaceEnabled = props.getProperty(USERSPACE_ENABLED, "no");
+ LOG.info("setUp: Using the following properties: mode= {}, ip:port= {}:{}, controller ip: {}, " +
+ "userspace.enabled: {}",
+ connectionType, addressStr, portStr, controllerStr, userSpaceEnabled);
if (connectionType.equalsIgnoreCase(CONNECTION_TYPE_ACTIVE)) {
if (addressStr == null) {
fail(usage());
}
LOG.info("getProperties {}: {}", OVSDB_TRACE, props.getProperty(OVSDB_TRACE));
LOG.info("getProperties {}: {}", OVSDB_WAIT, props.getProperty(OVSDB_WAIT));
- if (props.getProperty(OVSDB_WAIT).equals("true")) {
+ if (props.getProperty(OVSDB_WAIT) != null && props.getProperty(OVSDB_WAIT).equals("true")) {
ovsdb_wait = true;
}
}
assertTrue("Did not find " + NETVIRT_TOPOLOGY_ID, getNetvirtTopology());
southbound = (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
assertNotNull("southbound should not be null", southbound);
+ pipelineOrchestrator =
+ (PipelineOrchestrator) ServiceHelper.getGlobalInstance(PipelineOrchestrator.class, this);
+ assertNotNull("pipelineOrchestrator should not be null", pipelineOrchestrator);
setup.set(true);
}
testModelDelete(builder, clazz);
}
+ private <T extends DataObject> void testModel(Builder<T> builder, Class<T> clazz)
+ throws InterruptedException {
+ testModelPut(builder, clazz);
+ Thread.sleep(1000);
+ testModelDelete(builder, clazz);
+ }
+
private ServiceFunctionsBuilder serviceFunctionsBuilder() {
String sf1Name = SF1NAME;
String sf1Ip = SF1IP;
String sf2DplName = SF2DPLNAME;
String sn2Name = SN2NAME;
String bridge2Name= BRIDGE2NAME;
- int port = GPEPORT;
+ int port = GPEUDPPORT;
ServiceFunctionBuilder serviceFunctionBuilder =
serviceFunctionUtils.serviceFunctionBuilder(sf1Ip, port, sf1DplName, sff1Name, sf1Name);
String sn2Name = SN2NAME;
String bridge2Name= BRIDGE2NAME;
String aclName = ACLNAME;
- int port = GPEPORT;
+ int port = GPEUDPPORT;
ServiceFunctionForwarderBuilder serviceFunctionForwarderBuilder =
serviceFunctionForwarderUtils.serviceFunctionForwarderBuilder(
@Test
public void testSfcModel() throws InterruptedException {
- testModel(serviceFunctionsBuilder(), ServiceFunctions.class, 3000);
- testModel(serviceFunctionForwardersBuilder(), ServiceFunctionForwarders.class, 3000);
- testModel(serviceFunctionChainsBuilder(), ServiceFunctionChains.class, 3000);
- testModel(serviceFunctionPathsBuilder(), ServiceFunctionPaths.class, 3000);
+ int timeout = 1000;
+ testModel(serviceFunctionsBuilder(), ServiceFunctions.class, timeout);
+ testModel(serviceFunctionForwardersBuilder(), ServiceFunctionForwarders.class, timeout);
+ testModel(serviceFunctionChainsBuilder(), ServiceFunctionChains.class, timeout);
+ testModel(serviceFunctionPathsBuilder(), ServiceFunctionPaths.class, timeout);
}
@Test
public void testSfcModels() throws InterruptedException {
+ testModel(serviceFunctionsBuilder(), ServiceFunctions.class);
+ testModel(serviceFunctionForwardersBuilder(), ServiceFunctionForwarders.class);
+ testModel(serviceFunctionChainsBuilder(), ServiceFunctionChains.class);
+ testModel(serviceFunctionPathsBuilder(), ServiceFunctionPaths.class);
+
+ testModel(accessListsBuilder(), AccessLists.class);
+ testModel(classifiersBuilder(), Classifiers.class);
+ }
+
+ /**
+ * Test that the NetvirtSfc SfcClassifierService is added to the Netvirt pipeline.
+ * @throws InterruptedException
+ */
+ @Test
+ public void testNetvirtSfcPipeline() throws InterruptedException {
String bridgeName = INTEGRATION_BRIDGE_NAME;
- ConnectionInfo connectionInfo = southboundUtils.getConnectionInfo(addressStr, portStr);
+ ConnectionInfo connectionInfo = SouthboundUtils.getConnectionInfo(addressStr, portStr);
+ assertNotNull("connection failed", southboundUtils.connectOvsdbNode(connectionInfo));
+ Node ovsdbNode = southboundUtils.getOvsdbNode(connectionInfo);
+ assertNotNull("node is not connected", ovsdbNode);
+
+ assertTrue("Controller " + SouthboundUtils.connectionInfoToString(connectionInfo)
+ + " is not connected", isControllerConnected(connectionInfo));
+
+ Node bridgeNode = southbound.getBridgeNode(ovsdbNode, bridgeName);
+ assertNotNull("bridge " + bridgeName + " was not found", bridgeNode);
+ long datapathId = southbound.getDataPathId(bridgeNode);
+ String datapathIdString = southbound.getDatapathId(bridgeNode);
+ LOG.info("testNetVirt: bridgeNode: {}, datapathId: {} - {}", bridgeNode, datapathIdString, datapathId);
+ assertNotEquals("datapathId was not found", datapathId, 0);
+
+ String flowId = "DEFAULT_PIPELINE_FLOW_" + Service.SFC_CLASSIFIER.getTable();
+ verifyFlow(datapathId, flowId, Service.SFC_CLASSIFIER);
+
+ assertTrue(southboundUtils.deleteBridge(connectionInfo, bridgeName));
+ Thread.sleep(1000);
+ assertTrue(southboundUtils.disconnectOvsdbNode(connectionInfo));
+ }
+
+ /**
+ * Test the full NetvirtSfc functionality by creating everything needed to realize a chain and
+ * then verify all flows have been created.
+ * NOTE: This test requires an OVS with the NSH v8 patch, otherwise it will fail miserably.
+ * @throws InterruptedException
+ */
+ @Test
+ public void testNetvirtSfcAll() throws InterruptedException {
+ if (userSpaceEnabled.equals("yes")) {
+ LOG.info("testNetvirtSfcAll: skipping test because userSpaceEnabled {}", userSpaceEnabled);
+ return;
+ }
+ String bridgeName = INTEGRATION_BRIDGE_NAME;
+ ConnectionInfo connectionInfo = SouthboundUtils.getConnectionInfo(addressStr, portStr);
assertNotNull("connection failed", southboundUtils.connectOvsdbNode(connectionInfo));
Node ovsdbNode = southboundUtils.getOvsdbNode(connectionInfo);
assertNotNull("node is not connected", ovsdbNode);
- Thread.sleep(5000);
+ assertTrue("Controller " + SouthboundUtils.connectionInfoToString(connectionInfo)
+ + " is not connected", isControllerConnected(connectionInfo));
+
Node bridgeNode = southbound.getBridgeNode(ovsdbNode, bridgeName);
assertNotNull("bridge " + bridgeName + " was not found", bridgeNode);
long datapathId = southbound.getDataPathId(bridgeNode);
+ String datapathIdString = southbound.getDatapathId(bridgeNode);
+ LOG.info("testNetVirt: bridgeNode: {}, datapathId: {} - {}", bridgeNode, datapathIdString, datapathId);
+ assertNotEquals("datapathId was not found", datapathId, 0);
+
+ String flowId = "DEFAULT_PIPELINE_FLOW_" + Service.SFC_CLASSIFIER.getTable();
+ verifyFlow(datapathId, flowId, Service.SFC_CLASSIFIER);
Map<String, String> externalIds = Maps.newHashMap();
externalIds.put("attached-mac", "f6:00:00:0f:00:01");
southboundUtils.addTerminationPoint(bridgeNode, "vm2", "internal");
Map<String, String> options = Maps.newHashMap();
options.put("key", "flow");
+ options.put("dst_port", String.valueOf(GPEUDPPORT));
+ options.put("remote_ip", "flow");
+ options.put("nshc1", "flow");
+ options.put("nshc2", "flow");
+ options.put("nsp", "flow");
+ options.put("nsi", "flow");
+ southboundUtils.addTerminationPoint(bridgeNode, "vxgpe", "vxlan", options, null);
+ options.clear();
+ options.put("key", "flow");
options.put("remote_ip", "192.168.120.32");
southboundUtils.addTerminationPoint(bridgeNode, "vx", "vxlan", options, null);
- Thread.sleep(1000);
+ long vxGpeOfPort = getOFPort(bridgeNode, "vxgpe");
testModelPut(serviceFunctionsBuilder(), ServiceFunctions.class);
testModelPut(serviceFunctionForwardersBuilder(), ServiceFunctionForwarders.class);
testModelPut(serviceFunctionChainsBuilder(), ServiceFunctionChains.class);
testModelPut(serviceFunctionPathsBuilder(), ServiceFunctionPaths.class);
- Thread.sleep(5000);
-
testModelPut(accessListsBuilder(), AccessLists.class);
testModelPut(classifiersBuilder(), Classifiers.class);
- Thread.sleep(10000);
-
readwait();
- NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(datapathId);
- FlowBuilder flowBuilder = getSfcIngressClassifierFlowBuilder();
- Flow flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.CONFIGURATION);
- assertNotNull("Could not find flow in config", flow);
- flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.OPERATIONAL);
- assertNotNull("Could not find flow in operational", flow);
+ flowId = "sfcIngressClass_" + "httpRule";
+ verifyFlow(datapathId, flowId, Service.SFC_CLASSIFIER);
+ flowId = "sfcTable_" + vxGpeOfPort;
+ verifyFlow(datapathId, flowId, Service.CLASSIFIER);
+ flowId = "sfEgress_" + GPEUDPPORT;
+ verifyFlow(datapathId, flowId, Service.SFC_CLASSIFIER);
+ flowId = "sfIngress_" + GPEUDPPORT + "_" + SF1IP;
+ verifyFlow(datapathId, flowId, Service.CLASSIFIER);
+ flowId = "ArpResponder_" + SF1IP;
+ verifyFlow(datapathId, flowId, Service.CLASSIFIER);
assertTrue(southboundUtils.deleteBridge(connectionInfo, bridgeName));
Thread.sleep(1000);
assertTrue(southboundUtils.disconnectOvsdbNode(connectionInfo));
}
- /*
- * Connect to an ovsdb node. Netvirt should add br-int, add the controller address
- * and program the pipeline flows.
+ /**
+ * Test the standalone NetvirtSfc implementation
+ * NOTE: This test requires an OVS with the NSH v8 patch, otherwise it will fail miserably.
+ * @throws InterruptedException
*/
- @Test
- public void testNetvirtSfc() throws InterruptedException {
- String bridgeName = INTEGRATION_BRIDGE_NAME;
- ConnectionInfo connectionInfo = SouthboundUtils.getConnectionInfo(addressStr, portStr);
- assertNotNull("connection failed", southboundUtils.connectOvsdbNode(connectionInfo));
- Node ovsdbNode = southboundUtils.getOvsdbNode(connectionInfo);
- assertNotNull("node is not connected", ovsdbNode);
- ControllerEntry controllerEntry;
- // Loop 10s checking if the controller was added
- for (int i = 0; i < 10; i++) {
- ovsdbNode = southboundUtils.getOvsdbNode(connectionInfo);
- assertNotNull("ovsdb node not found", ovsdbNode);
- String controllerTarget = SouthboundUtil.getControllerTarget(ovsdbNode);
- assertNotNull("Failed to get controller target", controllerTarget);
- OvsdbBridgeAugmentation bridge = southboundUtils.getBridge(connectionInfo, bridgeName);
- if (bridge != null) {
- assertNotNull("Failed to read bridge", bridge);
- assertNotNull("Failed to extract controllerEntry", bridge.getControllerEntry());
- controllerEntry = bridge.getControllerEntry().iterator().next();
- assertEquals(controllerTarget, controllerEntry.getTarget().getValue());
- if (controllerEntry.isIsConnected()) {
- Assert.assertTrue("switch is not connected to the controller", controllerEntry.isIsConnected());
- break;
- }
- }
- Thread.sleep(1000);
- }
-
- Node bridgeNode = southbound.getBridgeNode(ovsdbNode, bridgeName);
- assertNotNull("bridge " + bridgeName + " was not found", bridgeNode);
- long datapathId = southbound.getDataPathId(bridgeNode);
-
- //Thread.sleep(10000);
-
- NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(datapathId);
- FlowBuilder flowBuilder = FlowUtils.getPipelineFlow(Service.SFC_CLASSIFIER.getTable(), (short)0);
- Flow flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.CONFIGURATION);
- assertNotNull("Could not find flow in config", flow);
- flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.OPERATIONAL);
- assertNotNull("Could not find flow in operational", flow);
-
- assertTrue(southboundUtils.deleteBridge(connectionInfo, bridgeName));
- Thread.sleep(1000);
- assertTrue(southboundUtils.disconnectOvsdbNode(connectionInfo));
- }
-
@Ignore
@Test
public void testStandalone() throws InterruptedException {
assertNotNull("connection failed", southboundUtils.connectOvsdbNode(connectionInfo));
Node ovsdbNode = southboundUtils.getOvsdbNode(connectionInfo);
assertNotNull("node is not connected", ovsdbNode);
+
String controllerTarget = "tcp:192.168.50.1:6653";
List<ControllerEntry> setControllerEntry = southboundUtils.createControllerEntry(controllerTarget);
Assert.assertTrue(southboundUtils.addBridge(connectionInfo, null, bridgeName, null, true,
SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null,
setControllerEntry, null, "00:00:00:00:00:00:00:01"));
- // Loop 10s checking if the controller was added
- for (int i = 0; i < 10; i++) {
- ovsdbNode = southboundUtils.getOvsdbNode(connectionInfo);
- assertNotNull("ovsdb node not found", ovsdbNode);
- assertNotNull("Failed to get controller target", controllerTarget);
- OvsdbBridgeAugmentation bridge = southboundUtils.getBridge(connectionInfo, bridgeName);
- assertNotNull(bridge);
- assertNotNull(bridge.getControllerEntry());
- ControllerEntry controllerEntry = bridge.getControllerEntry().iterator().next();
- assertEquals(controllerTarget, controllerEntry.getTarget().getValue());
- if (controllerEntry.isIsConnected()) {
- Assert.assertTrue(controllerEntry.isIsConnected());
- break;
- }
- Thread.sleep(1000);
- }
+ assertTrue("Controller " + SouthboundUtils.connectionInfoToString(connectionInfo)
+ + " is not connected", isControllerConnected(connectionInfo));
Node bridgeNode = southbound.getBridgeNode(ovsdbNode, bridgeName);
assertNotNull("bridge " + bridgeName + " was not found", bridgeNode);
long datapathId = southbound.getDataPathId(bridgeNode);
+ String datapathIdString = southbound.getDatapathId(bridgeNode);
+ LOG.info("testNetVirt: bridgeNode: {}, datapathId: {} - {}", bridgeNode, datapathIdString, datapathId);
+ assertNotEquals("datapathId was not found", datapathId, 0);
SfcClassifier sfcClassifier = new SfcClassifier(dataBroker, southbound, mdsalUtils);
//sfcClassifier.programLocalInPort(datapathId, "4096", (long)1, (short)0, (short)50, true);
sfcClassifier.programSfcClassiferFlows(datapathId, (short)0, "test", matchesBuilder.build(),
nshUtils, (long)2, true);
- nshUtils = new NshUtils(null, null, (long)10, (short)253, 0, 0);
+ //nshUtils = new NshUtils(null, null, (long)10, (short)253, 0, 0);
//sfcClassifier.programEgressSfcClassiferFlows(datapathId, (short)0, "test", null,
// nshUtils, (long)2, (long)3, true);
//}
//NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(datapathId);
- //FlowBuilder flowBuilder = getLocalInPortFlow(datapathId, "4096", (long) 1, (short) 0);
+ //FlowBuilder flowBuilder = getLocalInPortFlow(datapathId, "4096", (long) 1,
+ // pipelineOrchestrator.getTable(Service.CLASSIFIER));
//Flow flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.CONFIGURATION);
//assertNotNull("Could not find flow in config", flow);
//flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.OPERATIONAL);
//assertNotNull("Could not find flow in operational", flow);
- MatchBuilder matchBuilder = sfcClassifier.buildMatch(matchesBuilder.build());
- NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(datapathId);
- FlowBuilder flowBuilder = getSfcClassifierFlow(datapathId, (short) 0, "test", null,
- nshUtils, (long) 2, matchBuilder);
- Flow flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.CONFIGURATION);
- assertNotNull("Could not find flow in config", flow);
- flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.OPERATIONAL);
- assertNotNull("Could not find flow in operational", flow);
+ //MatchBuilder matchBuilder = sfcClassifier.buildMatch(matchesBuilder.build());
+ //NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(datapathId);
+ //FlowBuilder flowBuilder = getSfcClassifierFlow(datapathId,
+ // pipelineOrchestrator.getTable(Service.CLASSIFIER), "test", null,
+ // nshUtils, (long) 2, matchBuilder);
+ //Flow flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.CONFIGURATION);
+ //assertNotNull("Could not find flow in config", flow);
+ //flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.OPERATIONAL);
+ //assertNotNull("Could not find flow in operational", flow);
//nodeBuilder = FlowUtils.createNodeBuilder(datapathId);
- //flowBuilder = getEgressSfcClassifierFlow(datapathId, (short) 0, "test", nshUtils, (long) 2);
+ //flowBuilder = getEgressSfcClassifierFlow(datapathId,
+ //pipelineOrchestrator.getTable(Service.CLASSIFIER),
+ //"test", nshUtils, (long) 2);
//flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.CONFIGURATION);
//assertNotNull("Could not find flow in config", flow);
//flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.OPERATIONAL);
assertTrue(southboundUtils.disconnectOvsdbNode(connectionInfo));
}
- private FlowBuilder getLocalInPortFlow(long dpidLong, String segmentationId, long inPort, short writeTable) {
- MatchBuilder matchBuilder = new MatchBuilder();
-
- FlowBuilder flowBuilder = new FlowBuilder();
-
- flowBuilder.setMatch(MatchUtils.createInPortMatch(matchBuilder, dpidLong, inPort).build());
- String flowId = "sfcIngress_" + segmentationId + "_" + inPort;
- flowBuilder.setId(new FlowId(flowId));
- FlowKey key = new FlowKey(new FlowId(flowId));
- flowBuilder.setStrict(true);
- flowBuilder.setBarrier(false);
- flowBuilder.setTableId(writeTable);
- flowBuilder.setKey(key);
- flowBuilder.setFlowName(flowId);
- flowBuilder.setHardTimeout(0);
- flowBuilder.setIdleTimeout(0);
- return flowBuilder;
- }
-
- public FlowBuilder getSfcClassifierFlow(long dpidLong, short writeTable, String ruleName, Matches match,
- NshUtils nshHeader, long tunnelOfPort, MatchBuilder matchBuilder) {
- FlowBuilder flowBuilder = new FlowBuilder();
-
- flowBuilder.setMatch(matchBuilder.build());
-
- String flowId = "sfcClass_" + ruleName + "_" + nshHeader.getNshNsp();
- flowBuilder.setId(new FlowId(flowId));
- FlowKey key = new FlowKey(new FlowId(flowId));
- flowBuilder.setBarrier(true);
- flowBuilder.setTableId(writeTable);
- flowBuilder.setKey(key);
- flowBuilder.setFlowName(flowId);
- flowBuilder.setHardTimeout(0);
- flowBuilder.setIdleTimeout(0);
- return flowBuilder;
- }
-
- private FlowBuilder getEgressSfcClassifierFlow(long dpidLong, short writeTable, String ruleName,
- NshUtils nshHeader, long tunnelOfPort) {
- FlowBuilder flowBuilder = new FlowBuilder();
-
- MatchBuilder matchBuilder = new MatchBuilder();
- flowBuilder.setMatch(MatchUtils.createInPortMatch(matchBuilder, dpidLong, tunnelOfPort).build());
- flowBuilder.setMatch(
- MatchUtils.createTunnelIDMatch(matchBuilder, BigInteger.valueOf(nshHeader.getNshNsp())).build());
- flowBuilder.setMatch(MatchUtils.addNxNspMatch(matchBuilder, nshHeader.getNshNsp()).build());
- flowBuilder.setMatch(MatchUtils.addNxNsiMatch(matchBuilder, nshHeader.getNshNsi()).build());
-
- String flowId = "egressSfcClass_" + ruleName + "_" + nshHeader.getNshNsp() + "_" + nshHeader.getNshNsi();
- flowBuilder.setId(new FlowId(flowId));
- FlowKey key = new FlowKey(new FlowId(flowId));
- flowBuilder.setStrict(true);
- flowBuilder.setBarrier(false);
- flowBuilder.setTableId(writeTable);
- flowBuilder.setKey(key);
- flowBuilder.setFlowName(flowId);
- flowBuilder.setHardTimeout(0);
- flowBuilder.setIdleTimeout(0);
- return flowBuilder;
- }
-
- private FlowBuilder getSfcIngressClassifierFlowBuilder() {
- FlowBuilder flowBuilder = new FlowBuilder();
- String flowId = "sfcIngressClass_" + "httpRule";
- flowBuilder.setId(new FlowId(flowId));
- FlowKey key = new FlowKey(new FlowId(flowId));
- flowBuilder.setKey(key);
- flowBuilder.setFlowName(flowId);
- flowBuilder.setTableId((short)10);
- return flowBuilder;
- }
-
- private Flow getFlow (FlowBuilder flowBuilder, NodeBuilder nodeBuilder, LogicalDatastoreType store)
- throws InterruptedException {
+ private Flow getFlow (
+ FlowBuilder flowBuilder,
+ org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder nodeBuilder,
+ LogicalDatastoreType store) throws InterruptedException {
+
Flow flow = null;
for (int i = 0; i < 10; i++) {
+ LOG.info("getFlow try {} from {}: looking for flow: {}, node: {}",
+ i, store, flowBuilder.build(), nodeBuilder.build());
flow = FlowUtils.getFlow(flowBuilder, nodeBuilder, dataBroker.newReadOnlyTransaction(), store);
if (flow != null) {
- LOG.info("getFlow: flow: {}: {}", store, flow);
+ LOG.info("getFlow try {} from {}: found flow: {}", i, store, flow);
break;
}
Thread.sleep(1000);
return flow;
}
+ private void verifyFlow(long datapathId, String flowId, Service service) throws InterruptedException {
+ org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder nodeBuilder =
+ FlowUtils.createNodeBuilder(datapathId);
+ FlowBuilder flowBuilder =
+ FlowUtils.initFlowBuilder(new FlowBuilder(), flowId, pipelineOrchestrator.getTable(service));
+ Flow flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.CONFIGURATION);
+ assertNotNull("Could not find flow in config: " + flowBuilder.build() + "--" + nodeBuilder.build(), flow);
+ flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.OPERATIONAL);
+ assertNotNull("Could not find flow in operational: " + flowBuilder.build() + "--" + nodeBuilder.build(), flow);
+ }
+
private void readwait() {
if (ovsdb_wait) {
LOG.warn("Waiting, kill with ps -ef | grep java, kill xxx... ");
}
}
}
+
+ private boolean isControllerConnected(ConnectionInfo connectionInfo) throws InterruptedException {
+ LOG.info("isControllerConnected enter");
+ Boolean connected = false;
+ ControllerEntry controllerEntry;
+ Node ovsdbNode = southboundUtils.getOvsdbNode(connectionInfo);
+ assertNotNull("ovsdb node not found", ovsdbNode);
+
+ BridgeConfigurationManager bridgeConfigurationManager =
+ (BridgeConfigurationManager) ServiceHelper.getGlobalInstance(BridgeConfigurationManager.class, this);
+ assertNotNull("Could not find BridgeConfigurationManager Service", bridgeConfigurationManager);
+ String controllerTarget = bridgeConfigurationManager.getControllersFromOvsdbNode(ovsdbNode).get(0);
+ Assert.assertNotNull("Failed to get controller target", controllerTarget);
+
+ for (int i = 0; i < 10; i++) {
+ LOG.info("isControllerConnected try {}: looking for controller: {}", i, controllerTarget);
+ OvsdbBridgeAugmentation bridge =
+ southboundUtils.getBridge(connectionInfo, INTEGRATION_BRIDGE_NAME);
+ Assert.assertNotNull(bridge);
+ Assert.assertNotNull(bridge.getControllerEntry());
+ controllerEntry = bridge.getControllerEntry().iterator().next();
+ Assert.assertEquals(controllerTarget, controllerEntry.getTarget().getValue());
+ if (controllerEntry.isIsConnected()) {
+ Assert.assertTrue("Controller is not connected", controllerEntry.isIsConnected());
+ connected = true;
+ break;
+ }
+ Thread.sleep(1000);
+ }
+ LOG.info("isControllerConnected exit: {} - {}", connected, controllerTarget);
+ return connected;
+ }
+
+ private long getOFPort(Node bridgeNode, String portName) {
+ long ofPort = 0L;
+ OvsdbTerminationPointAugmentation port =
+ southbound.extractTerminationPointAugmentation(bridgeNode, portName);
+ if (port != null) {
+ ofPort = southbound.getOFPort(port);
+ }
+ if (ofPort == 0L) {
+ for (int i = 0; i < 10; i++) {
+ LOG.info("Looking for ofPort {}, try: {}", portName, i);
+ TerminationPoint tp = southbound.readTerminationPoint(bridgeNode, null, portName);
+ if (tp != null) {
+ port = tp.getAugmentation(OvsdbTerminationPointAugmentation.class);
+ if (port != null) {
+ ofPort = southbound.getOFPort(port);
+ LOG.info("found ofPort {} - {}, try: {}", portName, ofPort, i);
+ break;
+ }
+ }
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ LOG.error("Interrupted while waiting for ofPort {}", portName, e);
+ }
+ }
+ }
+ return ofPort;
+ }
}
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv4Builder;
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.packet.fields.rev150611.acl.transport.header.fields.DestinationPortRangeBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev150611.acl.transport.header.fields.SourcePortRange;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev150611.acl.transport.header.fields.SourcePortRangeBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.acl.rev150105.RedirectToSfc;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.acl.rev150105.RedirectToSfcBuilder;
public class AclUtils extends AbstractUtils {
public MatchesBuilder matchesBuilder(MatchesBuilder matchesBuilder, int destPort) {
+ SourcePortRangeBuilder sourcePortRangeBuilder = new SourcePortRangeBuilder()
+ .setLowerPort(PortNumber.getDefaultInstance("0"))
+ .setUpperPort(PortNumber.getDefaultInstance("0"));
+
PortNumber portNumber = new PortNumber(destPort);
DestinationPortRangeBuilder destinationPortRangeBuilder = new DestinationPortRangeBuilder()
.setLowerPort(portNumber)
.setUpperPort(portNumber);
AceIpBuilder aceIpBuilder = new AceIpBuilder()
+ .setSourcePortRange(sourcePortRangeBuilder.build())
.setDestinationPortRange(destinationPortRangeBuilder.build())
.setProtocol((short)6)
.setAceIpVersion(new AceIpv4Builder().build());
void programTunnelIn(Long dpidLong, String segmentationId, Long ofPort, boolean write);
void programVlanIn(Long dpidLong, String segmentationId, Long ethPort, boolean write);
void programLLDPPuntRule(Long dpidLong);
+ void programGotoTable(Long dpidLong, boolean write);
}