Michele Santuari
Committed by Gerrit Code Review

initial flows for corsa pipeline v39

- initial flows configuration
- moved to a dedicated folder
- refactoring super classes

Change-Id: Ie7452aed35d7947ca5f7246dd06fcbb87b2971b5
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2014-2016 Open Networking Laboratory
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>onos-drivers-general</artifactId>
<groupId>org.onosproject</groupId>
<version>1.6.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>onos-drivers-corsa</artifactId>
<packaging>bundle</packaging>
<description>Corsa device drivers</description>
<properties>
<onos.app.name>org.onosproject.drivers.corsa</onos.app.name>
<onos.app.origin>ON.Lab</onos.app.origin>
<onos.app.title>Corsa Device Drivers</onos.app.title>
<onos.app.category>Drivers</onos.app.category>
<onos.app.url>http://onosproject.org</onos.app.url>
<onos.app.requires>
org.onosproject.openflow
</onos.app.requires>
</properties>
<dependencies>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-of-api</artifactId>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>openflowj</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
......@@ -13,18 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.driver.pipeline;
package org.onosproject.drivers.corsa;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.RemovalCause;
import com.google.common.cache.RemovalNotification;
import org.onlab.osgi.ServiceDirectory;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IPv4;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onlab.util.KryoNamespace;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
......@@ -32,6 +29,7 @@ import org.onosproject.net.DeviceId;
import org.onosproject.net.behaviour.NextGroup;
import org.onosproject.net.behaviour.Pipeliner;
import org.onosproject.net.behaviour.PipelinerContext;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.driver.AbstractHandlerBehaviour;
import org.onosproject.net.flow.DefaultFlowRule;
import org.onosproject.net.flow.DefaultTrafficSelector;
......@@ -47,7 +45,6 @@ import org.onosproject.net.flow.criteria.Criterion;
import org.onosproject.net.flow.criteria.EthCriterion;
import org.onosproject.net.flow.criteria.EthTypeCriterion;
import org.onosproject.net.flow.criteria.IPCriterion;
import org.onosproject.net.flow.criteria.IPProtocolCriterion;
import org.onosproject.net.flow.criteria.PortCriterion;
import org.onosproject.net.flow.criteria.VlanIdCriterion;
import org.onosproject.net.flowobjective.FilteringObjective;
......@@ -81,26 +78,14 @@ import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import static org.onlab.util.Tools.groupedThreads;
import static org.onosproject.net.flow.FlowRule.Builder;
import static org.slf4j.LoggerFactory.getLogger;
/**
* OpenvSwitch emulation of the Corsa pipeline handler.
* Abstraction of the Corsa pipeline handler.
*/
public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeliner {
protected static final int MAC_TABLE = 0;
protected static final int VLAN_MPLS_TABLE = 1;
protected static final int VLAN_TABLE = 2;
//protected static final int MPLS_TABLE = 3;
protected static final int ETHER_TABLE = 4;
protected static final int COS_MAP_TABLE = 5;
protected static final int FIB_TABLE = 6;
protected static final int LOCAL_TABLE = 9;
public abstract class AbstractCorsaPipeline extends AbstractHandlerBehaviour implements Pipeliner {
protected static final int CONTROLLER_PRIORITY = 255;
protected static final int DROP_PRIORITY = 0;
protected static final int HIGHEST_PRIORITY = 0xffff;
private final Logger log = getLogger(getClass());
......@@ -112,6 +97,7 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli
private FlowObjectiveStore flowObjectiveStore;
protected DeviceId deviceId;
protected ApplicationId appId;
protected DeviceService deviceService;
private KryoNamespace appKryo = new KryoNamespace.Builder()
.register(GroupKey.class)
......@@ -124,8 +110,12 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli
private ScheduledExecutorService groupChecker =
Executors.newScheduledThreadPool(2, groupedThreads("onos/pipeliner",
"ovs-corsa-%d",
log));
"ovs-corsa-%d"));
protected static final int CONTROLLER_PRIORITY = 255;
protected static final int DROP_PRIORITY = 0;
protected static final int HIGHEST_PRIORITY = 0xffff;
protected static final String APPID = "org.onosproject.drivers.corsa.CorsaPipeline";
@Override
public void init(DeviceId deviceId, PipelinerContext context) {
......@@ -146,16 +136,90 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli
flowRuleService = serviceDirectory.get(FlowRuleService.class);
groupService = serviceDirectory.get(GroupService.class);
meterService = serviceDirectory.get(MeterService.class);
deviceService = serviceDirectory.get(DeviceService.class);
flowObjectiveStore = context.store();
groupService.addListener(new InnerGroupListener());
appId = coreService.registerApplication(
"org.onosproject.driver.OVSCorsaPipeline");
appId = coreService.registerApplication(APPID);
initializePipeline();
}
protected abstract void initializePipeline();
protected void pass(Objective obj) {
obj.context().ifPresent(context -> context.onSuccess(obj));
}
protected void fail(Objective obj, ObjectiveError error) {
obj.context().ifPresent(context -> context.onError(obj, error));
}
private class GroupChecker implements Runnable {
@Override
public void run() {
Set<GroupKey> keys = pendingGroups.asMap().keySet().stream()
.filter(key -> groupService.getGroup(deviceId, key) != null)
.collect(Collectors.toSet());
keys.stream().forEach(key -> {
NextObjective obj = pendingGroups.getIfPresent(key);
if (obj == null) {
return;
}
pass(obj);
pendingGroups.invalidate(key);
log.info("Heard back from group service for group {}. "
+ "Applying pending forwarding objectives", obj.id());
flowObjectiveStore.putNextGroup(obj.id(), new CorsaGroup(key));
});
}
}
private class CorsaGroup implements NextGroup {
private final GroupKey key;
public CorsaGroup(GroupKey key) {
this.key = key;
}
public GroupKey key() {
return key;
}
@Override
public byte[] data() {
return appKryo.serialize(key);
}
}
@Override
public List<String> getNextMappings(NextGroup nextGroup) {
//TODO: to be implemented
return Collections.emptyList();
}
private class InnerGroupListener implements GroupListener {
@Override
public void event(GroupEvent event) {
if (event.type() == GroupEvent.Type.GROUP_ADDED) {
GroupKey key = event.subject().appCookie();
NextObjective obj = pendingGroups.getIfPresent(key);
if (obj != null) {
flowObjectiveStore.putNextGroup(obj.id(), new CorsaGroup(key));
pass(obj);
pendingGroups.invalidate(key);
}
}
}
}
@Override
public void filter(FilteringObjective filteringObjective) {
if (filteringObjective.type() == FilteringObjective.Type.PERMIT) {
......@@ -167,6 +231,76 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli
}
}
private void processFilter(FilteringObjective filt, boolean install,
ApplicationId applicationId) {
// This driver only processes filtering criteria defined with switch
// ports as the key
PortCriterion port;
if (!filt.key().equals(Criteria.dummy()) &&
filt.key().type() == Criterion.Type.IN_PORT) {
port = (PortCriterion) filt.key();
} else {
log.warn("No key defined in filtering objective from app: {}. Not"
+ "processing filtering objective", applicationId);
fail(filt, ObjectiveError.UNKNOWN);
return;
}
// convert filtering conditions for switch-intfs into flowrules
FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
for (Criterion c : filt.conditions()) {
if (c.type() == Criterion.Type.ETH_DST) {
EthCriterion eth = (EthCriterion) c;
FlowRule.Builder rule = processEthFiler(filt, eth, port);
rule.forDevice(deviceId)
.fromApp(applicationId);
ops = install ? ops.add(rule.build()) : ops.remove(rule.build());
} else if (c.type() == Criterion.Type.VLAN_VID) {
VlanIdCriterion vlan = (VlanIdCriterion) c;
FlowRule.Builder rule = processVlanFiler(filt, vlan, port);
rule.forDevice(deviceId)
.fromApp(applicationId);
ops = install ? ops.add(rule.build()) : ops.remove(rule.build());
} else if (c.type() == Criterion.Type.IPV4_DST) {
IPCriterion ip = (IPCriterion) c;
FlowRule.Builder rule = processIpFilter(filt, ip, port);
rule.forDevice(deviceId)
.fromApp(applicationId);
ops = install ? ops.add(rule.build()) : ops.remove(rule.build());
} else {
log.warn("Driver does not currently process filtering condition"
+ " of type: {}", c.type());
fail(filt, ObjectiveError.UNSUPPORTED);
}
}
// apply filtering flow rules
flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
@Override
public void onSuccess(FlowRuleOperations ops) {
pass(filt);
log.info("Applied filtering rules");
}
@Override
public void onError(FlowRuleOperations ops) {
fail(filt, ObjectiveError.FLOWINSTALLATIONFAILED);
log.info("Failed to apply filtering rules");
}
}));
}
protected abstract Builder processEthFiler(FilteringObjective filt,
EthCriterion eth, PortCriterion port);
protected abstract Builder processVlanFiler(FilteringObjective filt,
VlanIdCriterion vlan, PortCriterion port);
protected abstract Builder processIpFilter(FilteringObjective filt,
IPCriterion ip, PortCriterion port);
@Override
public void forward(ForwardingObjective fwd) {
Collection<FlowRule> rules;
......@@ -189,7 +323,6 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli
log.warn("Unknown forwarding type {}", fwd.op());
}
flowRuleService.apply(flowBuilder.build(new FlowRuleOperationsContext() {
@Override
public void onSuccess(FlowRuleOperations ops) {
......@@ -204,47 +337,6 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli
}
@Override
public void next(NextObjective nextObjective) {
switch (nextObjective.type()) {
case SIMPLE:
Collection<TrafficTreatment> treatments = nextObjective.next();
if (treatments.size() == 1) {
TrafficTreatment treatment = treatments.iterator().next();
treatment = processNextTreatment(treatment);
GroupBucket bucket =
DefaultGroupBucket.createIndirectGroupBucket(treatment);
final GroupKey key = new DefaultGroupKey(appKryo.serialize(nextObjective.id()));
GroupDescription groupDescription
= new DefaultGroupDescription(deviceId,
GroupDescription.Type.INDIRECT,
new GroupBuckets(Collections
.singletonList(bucket)),
key,
null, // let group service determine group id
nextObjective.appId());
groupService.addGroup(groupDescription);
pendingGroups.put(key, nextObjective);
}
break;
case HASHED:
case BROADCAST:
case FAILOVER:
fail(nextObjective, ObjectiveError.UNSUPPORTED);
log.warn("Unsupported next objective type {}", nextObjective.type());
break;
default:
fail(nextObjective, ObjectiveError.UNKNOWN);
log.warn("Unknown next objective type {}", nextObjective.type());
}
}
/* Hook for altering the NextObjective treatment */
protected TrafficTreatment processNextTreatment(TrafficTreatment treatment) {
return treatment; /* Keep treatment as is for OVSCorsaPipeline */
}
private Collection<FlowRule> processForward(ForwardingObjective fwd) {
switch (fwd.flag()) {
case SPECIFIC:
......@@ -258,78 +350,69 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli
return Collections.emptySet();
}
private Collection<FlowRule> processVersatile(ForwardingObjective fwd) {
log.debug("Processing versatile forwarding objective");
private Collection<FlowRule> processSpecific(ForwardingObjective fwd) {
log.debug("Processing specific forwarding objective");
TrafficSelector selector = fwd.selector();
EthTypeCriterion ethType =
(EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
if (ethType == null) {
log.error("Versatile forwarding objective must include ethType");
fail(fwd, ObjectiveError.UNKNOWN);
return Collections.emptySet();
if (ethType != null) {
short et = ethType.ethType().toShort();
if (et == Ethernet.TYPE_IPV4) {
return processSpecificRoute(fwd);
} else if (et == Ethernet.TYPE_VLAN) {
/* The ForwardingObjective must specify VLAN ethtype in order to use the Transit Circuit */
return processSpecificSwitch(fwd);
}
if (ethType.ethType().toShort() == Ethernet.TYPE_ARP) {
log.warn("Driver automatically handles ARP packets by punting to controller "
+ " from ETHER table");
pass(fwd);
return Collections.emptySet();
} else if (ethType.ethType().toShort() == Ethernet.TYPE_LLDP ||
ethType.ethType().toShort() == Ethernet.TYPE_BSN) {
log.warn("Driver currently does not currently handle LLDP packets");
fail(fwd, ObjectiveError.UNSUPPORTED);
return Collections.emptySet();
} else if (ethType.ethType().toShort() == Ethernet.TYPE_IPV4) {
IPCriterion ipSrc = (IPCriterion) selector
.getCriterion(Criterion.Type.IPV4_SRC);
IPCriterion ipDst = (IPCriterion) selector
.getCriterion(Criterion.Type.IPV4_DST);
IPProtocolCriterion ipProto = (IPProtocolCriterion) selector
.getCriterion(Criterion.Type.IP_PROTO);
if (ipSrc != null) {
log.warn("Driver does not currently handle matching Src IP");
fail(fwd, ObjectiveError.UNSUPPORTED);
return Collections.emptySet();
}
if (ipDst != null) {
log.error("Driver handles Dst IP matching as specific forwarding "
+ "objective, not versatile");
fail(fwd, ObjectiveError.UNSUPPORTED);
return Collections.emptySet();
}
if (ipProto != null && ipProto.protocol() == IPv4.PROTOCOL_TCP) {
log.warn("Driver automatically punts all packets reaching the "
+ "LOCAL table to the controller");
pass(fwd);
return Collections.emptySet();
}
}
log.warn("Driver does not support given versatile forwarding objective");
protected Collection<FlowRule> processSpecificSwitch(ForwardingObjective fwd) {
/* Not supported by until CorsaPipelineV3 */
log.warn("Vlan switching not supported in ovs-corsa driver");
fail(fwd, ObjectiveError.UNSUPPORTED);
return Collections.emptySet();
}
private Collection<FlowRule> processSpecific(ForwardingObjective fwd) {
log.debug("Processing specific forwarding objective");
private Collection<FlowRule> processVersatile(ForwardingObjective fwd) {
log.debug("Processing vesatile forwarding objective");
TrafficSelector selector = fwd.selector();
EthTypeCriterion ethType =
(EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
if (ethType != null) {
short et = ethType.ethType().toShort();
if (et == Ethernet.TYPE_IPV4) {
return processSpecificRoute(fwd);
} else if (et == Ethernet.TYPE_VLAN) {
/* The ForwardingObjective must specify VLAN ethtype in order to use the Transit Circuit */
return processSpecificSwitch(fwd);
if (ethType == null) {
log.error("Versatile forwarding objective must include ethType");
fail(fwd, ObjectiveError.UNKNOWN);
return Collections.emptySet();
}
Builder rule = DefaultFlowRule.builder()
.forDevice(deviceId)
.withSelector(fwd.selector())
.withTreatment(fwd.treatment())
.withPriority(fwd.priority())
.fromApp(fwd.appId())
.makePermanent();
if (ethType.ethType().toShort() == Ethernet.TYPE_ARP) {
return processArpTraffic(fwd, rule);
} else if (ethType.ethType().toShort() == Ethernet.TYPE_LLDP ||
ethType.ethType().toShort() == Ethernet.TYPE_BSN) {
return processLinkDiscovery(fwd, rule);
} else if (ethType.ethType().toShort() == Ethernet.TYPE_IPV4) {
return processIpTraffic(fwd, rule);
}
log.warn("Driver does not support given versatile forwarding objective");
fail(fwd, ObjectiveError.UNSUPPORTED);
return Collections.emptySet();
}
protected abstract Collection<FlowRule> processArpTraffic(ForwardingObjective fwd, Builder rule);
protected abstract Collection<FlowRule> processLinkDiscovery(ForwardingObjective fwd, Builder rule);
protected abstract Collection<FlowRule> processIpTraffic(ForwardingObjective fwd, Builder rule);
private Collection<FlowRule> processSpecificRoute(ForwardingObjective fwd) {
TrafficSelector filteredSelector =
DefaultTrafficSelector.builder()
......@@ -351,8 +434,7 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli
}
tb.group(group.id());
}
FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
Builder ruleBuilder = DefaultFlowRule.builder()
.fromApp(fwd.appId())
.withPriority(fwd.priority())
.forDevice(deviceId)
......@@ -366,503 +448,111 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli
} else {
ruleBuilder.makeTemporary(fwd.timeout());
}
return Collections.singletonList(ruleBuilder.build());
}
/* Hook for modifying Route traffic treatment */
//Hook for modifying Route traffic treatment
protected TrafficTreatment.Builder processSpecificRoutingTreatment() {
return DefaultTrafficTreatment.builder();
}
/* Hook for modifying Route flow rule */
protected FlowRule.Builder processSpecificRoutingRule(FlowRule.Builder rb) {
return rb.forTable(FIB_TABLE);
}
protected Collection<FlowRule> processSpecificSwitch(ForwardingObjective fwd) {
/* Not supported by until CorsaPipelineV3 */
log.warn("Vlan switching not supported in ovs-corsa driver");
fail(fwd, ObjectiveError.UNSUPPORTED);
return Collections.emptySet();
}
protected void processFilter(FilteringObjective filt, boolean install,
ApplicationId applicationId) {
// This driver only processes filtering criteria defined with switch
// ports as the key
PortCriterion p;
if (!filt.key().equals(Criteria.dummy()) &&
filt.key().type() == Criterion.Type.IN_PORT) {
p = (PortCriterion) filt.key();
} else {
log.warn("No key defined in filtering objective from app: {}. Not"
+ "processing filtering objective", applicationId);
fail(filt, ObjectiveError.UNKNOWN);
return;
}
// convert filtering conditions for switch-intfs into flowrules
FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
for (Criterion c : filt.conditions()) {
if (c.type() == Criterion.Type.ETH_DST) {
EthCriterion e = (EthCriterion) c;
log.debug("adding rule for MAC: {}", e.mac());
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
selector.matchEthDst(e.mac());
treatment.transition(VLAN_MPLS_TABLE);
FlowRule rule = DefaultFlowRule.builder()
.forDevice(deviceId)
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(CONTROLLER_PRIORITY)
.fromApp(applicationId)
.makePermanent()
.forTable(MAC_TABLE).build();
ops = install ? ops.add(rule) : ops.remove(rule);
} else if (c.type() == Criterion.Type.VLAN_VID) {
VlanIdCriterion v = (VlanIdCriterion) c;
log.debug("adding rule for VLAN: {}", v.vlanId());
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
selector.matchVlanId(v.vlanId());
selector.matchInPort(p.port());
treatment.transition(ETHER_TABLE);
treatment.deferred().popVlan();
FlowRule rule = DefaultFlowRule.builder()
.forDevice(deviceId)
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(CONTROLLER_PRIORITY)
.fromApp(applicationId)
.makePermanent()
.forTable(VLAN_TABLE).build();
ops = install ? ops.add(rule) : ops.remove(rule);
} else if (c.type() == Criterion.Type.IPV4_DST) {
IPCriterion ip = (IPCriterion) c;
log.debug("adding rule for IP: {}", ip.ip());
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
selector.matchEthType(Ethernet.TYPE_IPV4);
selector.matchIPDst(ip.ip());
treatment.transition(LOCAL_TABLE);
FlowRule rule = DefaultFlowRule.builder()
.forDevice(deviceId)
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(HIGHEST_PRIORITY)
.fromApp(applicationId)
.makePermanent()
.forTable(FIB_TABLE).build();
ops = install ? ops.add(rule) : ops.remove(rule);
} else {
log.warn("Driver does not currently process filtering condition"
+ " of type: {}", c.type());
fail(filt, ObjectiveError.UNSUPPORTED);
}
}
// apply filtering flow rules
flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
@Override
public void onSuccess(FlowRuleOperations ops) {
pass(filt);
log.info("Applied filtering rules");
}
@Override
public void onError(FlowRuleOperations ops) {
fail(filt, ObjectiveError.FLOWINSTALLATIONFAILED);
log.info("Failed to apply filtering rules");
}
}));
}
protected void pass(Objective obj) {
obj.context().ifPresent(context -> context.onSuccess(obj));
}
protected void fail(Objective obj, ObjectiveError error) {
obj.context().ifPresent(context -> context.onError(obj, error));
}
protected void initializePipeline() {
processMacTable(true);
processVlanMplsTable(true);
processVlanTable(true);
processEtherTable(true);
processCosTable(true);
processFibTable(true);
processLocalTable(true);
}
private void processMacTable(boolean install) {
TrafficSelector.Builder selector;
TrafficTreatment.Builder treatment;
// Bcast rule
selector = DefaultTrafficSelector.builder();
treatment = DefaultTrafficTreatment.builder();
selector.matchEthDst(MacAddress.BROADCAST);
treatment.transition(VLAN_MPLS_TABLE);
FlowRule rule = DefaultFlowRule.builder()
.forDevice(deviceId)
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(CONTROLLER_PRIORITY)
.fromApp(appId)
.makePermanent()
.forTable(MAC_TABLE).build();
FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
ops = install ? ops.add(rule) : ops.remove(rule);
//Drop rule
selector = DefaultTrafficSelector.builder();
treatment = DefaultTrafficTreatment.builder();
treatment.drop();
rule = DefaultFlowRule.builder()
.forDevice(deviceId)
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(DROP_PRIORITY)
.fromApp(appId)
.makePermanent()
.forTable(MAC_TABLE).build();
ops = install ? ops.add(rule) : ops.remove(rule);
flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
@Override
public void onSuccess(FlowRuleOperations ops) {
log.info("Provisioned mac table");
}
@Override
public void onError(FlowRuleOperations ops) {
log.info("Failed to provision mac table");
}
}));
}
protected void processVlanMplsTable(boolean install) {
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment
.builder();
FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
FlowRule rule;
selector.matchVlanId(VlanId.ANY);
treatment.transition(VLAN_TABLE);
rule = DefaultFlowRule.builder()
.forDevice(deviceId)
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(CONTROLLER_PRIORITY)
.fromApp(appId)
.makePermanent()
.forTable(VLAN_MPLS_TABLE).build();
ops = install ? ops.add(rule) : ops.remove(rule);
flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
@Override
public void onSuccess(FlowRuleOperations ops) {
log.info("Provisioned vlan/mpls table");
}
//Hook for modifying Route flow rule
protected abstract Builder processSpecificRoutingRule(Builder rb);
@Override
public void onError(FlowRuleOperations ops) {
log.info(
"Failed to provision vlan/mpls table");
public void next(NextObjective nextObjective) {
switch (nextObjective.type()) {
case SIMPLE:
Collection<TrafficTreatment> treatments = nextObjective.next();
if (treatments.size() == 1) {
TrafficTreatment treatment = treatments.iterator().next();
treatment = processNextTreatment(treatment);
GroupBucket bucket =
DefaultGroupBucket.createIndirectGroupBucket(treatment);
final GroupKey key = new DefaultGroupKey(appKryo.serialize(nextObjective.id()));
GroupDescription groupDescription
= new DefaultGroupDescription(deviceId,
GroupDescription.Type.INDIRECT,
new GroupBuckets(Collections
.singletonList(bucket)),
key,
null, // let group service determine group id
nextObjective.appId());
groupService.addGroup(groupDescription);
pendingGroups.put(key, nextObjective);
}
}));
break;
case HASHED:
case BROADCAST:
case FAILOVER:
fail(nextObjective, ObjectiveError.UNSUPPORTED);
log.warn("Unsupported next objective type {}", nextObjective.type());
break;
default:
fail(nextObjective, ObjectiveError.UNKNOWN);
log.warn("Unknown next objective type {}", nextObjective.type());
}
private void processVlanTable(boolean install) {
TrafficSelector.Builder selector;
TrafficTreatment.Builder treatment;
FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
FlowRule rule;
//Drop rule
selector = DefaultTrafficSelector.builder();
treatment = DefaultTrafficTreatment.builder();
treatment.drop();
rule = DefaultFlowRule.builder()
.forDevice(deviceId)
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(DROP_PRIORITY)
.fromApp(appId)
.makePermanent()
.forTable(VLAN_TABLE).build();
ops = install ? ops.add(rule) : ops.remove(rule);
flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
@Override
public void onSuccess(FlowRuleOperations ops) {
log.info("Provisioned vlan table");
}
@Override
public void onError(FlowRuleOperations ops) {
log.info("Failed to provision vlan table");
}
}));
//Hook for altering the NextObjective treatment
protected TrafficTreatment processNextTreatment(TrafficTreatment treatment) {
return treatment;
}
private void processEtherTable(boolean install) {
//Init helper: Table Miss = Drop
protected void processTableMissDrop(boolean install, int table, String description) {
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment
.builder();
FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
FlowRule rule;
selector.matchEthType(Ethernet.TYPE_ARP);
treatment.punt();
rule = DefaultFlowRule.builder()
.forDevice(deviceId)
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(CONTROLLER_PRIORITY)
.fromApp(appId)
.makePermanent()
.forTable(ETHER_TABLE).build();
ops = install ? ops.add(rule) : ops.remove(rule);
selector = DefaultTrafficSelector.builder();
treatment = DefaultTrafficTreatment.builder();
selector.matchEthType(Ethernet.TYPE_IPV4);
treatment.transition(COS_MAP_TABLE);
rule = DefaultFlowRule.builder()
.forDevice(deviceId)
.withPriority(CONTROLLER_PRIORITY)
.withSelector(selector.build())
.withTreatment(treatment.build())
.fromApp(appId)
.makePermanent()
.forTable(ETHER_TABLE).build();
ops = install ? ops.add(rule) : ops.remove(rule);
//Drop rule
selector = DefaultTrafficSelector.builder();
treatment = DefaultTrafficTreatment.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
treatment.drop();
rule = DefaultFlowRule.builder()
FlowRule rule = DefaultFlowRule.builder()
.forDevice(deviceId)
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(DROP_PRIORITY)
.fromApp(appId)
.makePermanent()
.forTable(ETHER_TABLE).build();
ops = install ? ops.add(rule) : ops.remove(rule);
flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
@Override
public void onSuccess(FlowRuleOperations ops) {
log.info("Provisioned ether table");
}
@Override
public void onError(FlowRuleOperations ops) {
log.info("Failed to provision ether table");
}
}));
.forTable(table).build();
processFlowRule(install, rule, description);
}
private void processCosTable(boolean install) {
//Init helper: Table Miss = GoTo
protected void processTableMissGoTo(boolean install, int table, int goTo, String description) {
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment
.builder();
FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
FlowRule rule;
treatment.transition(FIB_TABLE);
rule = DefaultFlowRule.builder()
.forDevice(deviceId)
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(DROP_PRIORITY)
.fromApp(appId)
.makePermanent()
.forTable(COS_MAP_TABLE).build();
ops = install ? ops.add(rule) : ops.remove(rule);
flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
@Override
public void onSuccess(FlowRuleOperations ops) {
log.info("Provisioned cos table");
}
@Override
public void onError(FlowRuleOperations ops) {
log.info("Failed to provision cos table");
}
}));
}
private void processFibTable(boolean install) {
TrafficSelector.Builder selector;
TrafficTreatment.Builder treatment;
FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
FlowRule rule;
//Drop rule
selector = DefaultTrafficSelector.builder();
treatment = DefaultTrafficTreatment.builder();
treatment.drop();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
treatment.transition(goTo);
rule = DefaultFlowRule.builder()
FlowRule rule = DefaultFlowRule.builder()
.forDevice(deviceId)
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(DROP_PRIORITY)
.fromApp(appId)
.makePermanent()
.forTable(FIB_TABLE).build();
ops = install ? ops.add(rule) : ops.remove(rule);
.forTable(table).build();
flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
@Override
public void onSuccess(FlowRuleOperations ops) {
log.info("Provisioned FIB table");
}
@Override
public void onError(FlowRuleOperations ops) {
log.info("Failed to provision FIB table");
}
}));
processFlowRule(install, rule, description);
}
private void processLocalTable(boolean install) {
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment
.builder();
//Init helper: Apply flow rule
protected void processFlowRule(boolean install, FlowRule rule, String description) {
FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
FlowRule rule;
treatment.punt();
rule = DefaultFlowRule.builder()
.forDevice(deviceId)
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(CONTROLLER_PRIORITY)
.fromApp(appId)
.makePermanent()
.forTable(LOCAL_TABLE).build();
ops = install ? ops.add(rule) : ops.remove(rule);
flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
@Override
public void onSuccess(FlowRuleOperations ops) {
log.info("Provisioned Local table");
log.info(description + " success: " + ops.toString() + ", " + rule.toString());
}
@Override
public void onError(FlowRuleOperations ops) {
log.info("Failed to provision Local table");
log.info(description + " error: " + ops.toString() + ", " + rule.toString());
}
}));
}
private class InnerGroupListener implements GroupListener {
@Override
public void event(GroupEvent event) {
if (event.type() == GroupEvent.Type.GROUP_ADDED) {
GroupKey key = event.subject().appCookie();
NextObjective obj = pendingGroups.getIfPresent(key);
if (obj != null) {
flowObjectiveStore.putNextGroup(obj.id(), new CorsaGroup(key));
pass(obj);
pendingGroups.invalidate(key);
}
}
}
}
private class GroupChecker implements Runnable {
@Override
public void run() {
Set<GroupKey> keys = pendingGroups.asMap().keySet().stream()
.filter(key -> groupService.getGroup(deviceId, key) != null)
.collect(Collectors.toSet());
keys.stream().forEach(key -> {
NextObjective obj = pendingGroups.getIfPresent(key);
if (obj == null) {
return;
}
pass(obj);
pendingGroups.invalidate(key);
log.info("Heard back from group service for group {}. "
+ "Applying pending forwarding objectives", obj.id());
flowObjectiveStore.putNextGroup(obj.id(), new CorsaGroup(key));
});
}
}
private class CorsaGroup implements NextGroup {
private final GroupKey key;
public CorsaGroup(GroupKey key) {
this.key = key;
}
@SuppressWarnings("unused")
public GroupKey key() {
return key;
}
@Override
public byte[] data() {
return appKryo.serialize(key);
}
}
@Override
public List<String> getNextMappings(NextGroup nextGroup) {
// TODO Implementation deferred to vendor
return null;
}
}
......
/*
* Copyright 2014-2016 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.drivers.corsa;
import org.apache.felix.scr.annotations.Component;
import org.onosproject.net.driver.AbstractDriverLoader;
/**
* Loader for Corsa device drivers.
*/
@Component(immediate = true)
public class CorsaDriversLoader extends AbstractDriverLoader {
public CorsaDriversLoader() {
super("/corsa-drivers.xml");
}
}
......@@ -13,9 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.driver.pipeline;
import static org.slf4j.LoggerFactory.getLogger;
package org.onosproject.drivers.corsa;
import org.onlab.packet.Ethernet;
import org.onosproject.net.flow.DefaultFlowRule;
......@@ -26,18 +24,15 @@ import org.onosproject.net.flow.FlowRuleOperations;
import org.onosproject.net.flow.FlowRuleOperationsContext;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flowobjective.ForwardingObjective;
import org.onosproject.net.flowobjective.ObjectiveError;
import org.slf4j.Logger;
import java.util.Collection;
import java.util.Collections;
import static org.slf4j.LoggerFactory.getLogger;
/**
* Driver for Corsa TTP.
*
*/
public class CorsaPipeline extends OVSCorsaPipeline {
public class CorsaPipelineV1 extends OvsCorsaPipeline {
private final Logger log = getLogger(getClass());
......@@ -76,13 +71,4 @@ public class CorsaPipeline extends OVSCorsaPipeline {
}
}));
}
@Override
protected Collection<FlowRule> processSpecificSwitch(ForwardingObjective fwd) {
/* Not supported by until CorsaPipelineV3 */
log.warn("Vlan switching not supported in corsa-v1 driver");
fail(fwd, ObjectiveError.UNSUPPORTED);
return Collections.emptySet();
}
}
......
......@@ -13,31 +13,25 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.driver.pipeline;
package org.onosproject.drivers.corsa;
import org.onlab.packet.Ethernet;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.flow.DefaultFlowRule;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.FlowRuleOperations;
import org.onosproject.net.flow.FlowRuleOperationsContext;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flow.criteria.Criteria;
import org.onosproject.net.flow.criteria.Criterion;
import org.onosproject.net.flow.criteria.EthCriterion;
import org.onosproject.net.flow.criteria.IPCriterion;
import org.onosproject.net.flow.criteria.PortCriterion;
import org.onosproject.net.flow.criteria.VlanIdCriterion;
import org.onosproject.net.flow.instructions.Instructions;
import org.onosproject.net.flow.instructions.L2ModificationInstruction;
import org.onosproject.net.flowobjective.FilteringObjective;
import org.onosproject.net.flowobjective.ForwardingObjective;
import org.onosproject.net.flowobjective.ObjectiveError;
import org.onosproject.net.meter.Band;
import org.onosproject.net.meter.DefaultBand;
import org.onosproject.net.meter.DefaultMeterRequest;
......@@ -49,9 +43,13 @@ import org.slf4j.Logger;
import java.util.Collection;
import java.util.Collections;
import static org.onosproject.net.flow.FlowRule.Builder;
import static org.slf4j.LoggerFactory.getLogger;
public class CorsaPipelineV3 extends OVSCorsaPipeline {
/**
* Implementation of the Corsa pipeline handler for pipeline version 3.
*/
public class CorsaPipelineV3 extends AbstractCorsaPipeline {
private final Logger log = getLogger(getClass());
......@@ -67,17 +65,27 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline {
protected static final byte MAX_VLAN_PCP = 7;
private MeterId defaultMeterId = null;
protected MeterId defaultMeterId = null;
@Override
protected TrafficTreatment processNextTreatment(TrafficTreatment treatment) {
TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder();
treatment.immediate().stream()
.filter(i -> i instanceof L2ModificationInstruction.ModVlanIdInstruction ||
i instanceof L2ModificationInstruction.ModEtherInstruction ||
i instanceof Instructions.OutputInstruction)
.forEach(i -> tb.add(i));
.filter(i -> {
switch (i.type()) {
case L2MODIFICATION:
L2ModificationInstruction l2i = (L2ModificationInstruction) i;
if (l2i instanceof L2ModificationInstruction.ModVlanIdInstruction ||
l2i instanceof L2ModificationInstruction.ModEtherInstruction) {
return true;
}
case OUTPUT:
return true;
default:
return false;
}
}).forEach(i -> tb.add(i));
return tb.build();
}
......@@ -87,7 +95,7 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline {
}
@Override
protected FlowRule.Builder processSpecificRoutingRule(FlowRule.Builder rb) {
protected Builder processSpecificRoutingRule(Builder rb) {
return rb.forTable(FIB_TABLE);
}
......@@ -101,7 +109,7 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline {
((VlanIdCriterion) fwd.selector().getCriterion(Criterion.Type.VLAN_VID)).vlanId())
.build();
FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
Builder ruleBuilder = DefaultFlowRule.builder()
.fromApp(fwd.appId())
.withPriority(fwd.priority())
.forDevice(deviceId)
......@@ -119,101 +127,76 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline {
}
@Override
protected void processFilter(FilteringObjective filt, boolean install,
ApplicationId applicationId) {
// This driver only processes filtering criteria defined with switch
// ports as the key
PortCriterion p;
if (!filt.key().equals(Criteria.dummy()) &&
filt.key().type() == Criterion.Type.IN_PORT) {
p = (PortCriterion) filt.key();
} else {
log.warn("No key defined in filtering objective from app: {}. Not"
+ "processing filtering objective", applicationId);
fail(filt, ObjectiveError.UNKNOWN);
return;
protected Collection<FlowRule> processArpTraffic(ForwardingObjective fwd, Builder rule) {
//TODO
return Collections.emptyList();
}
@Override
protected Collection<FlowRule> processLinkDiscovery(ForwardingObjective fwd, Builder rule) {
//TODO
return Collections.emptyList();
}
@Override
protected Collection<FlowRule> processIpTraffic(ForwardingObjective fwd, Builder rule) {
//TODO
return Collections.emptyList();
}
// convert filtering conditions for switch-intfs into flowrules
FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
for (Criterion c : filt.conditions()) {
if (c.type() == Criterion.Type.ETH_DST) {
EthCriterion e = (EthCriterion) c;
log.debug("adding rule for MAC: {}", e.mac());
@Override
protected Builder processEthFiler(FilteringObjective filt, EthCriterion eth, PortCriterion port) {
log.debug("adding rule for MAC: {}", eth.mac());
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
selector.matchEthDst(e.mac());
selector.matchInPort(p.port());
selector.matchEthDst(eth.mac());
selector.matchInPort(port.port());
treatment.transition(ETHER_TABLE);
FlowRule rule = DefaultFlowRule.builder()
.forDevice(deviceId)
return DefaultFlowRule.builder()
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(CONTROLLER_PRIORITY)
.fromApp(applicationId)
.makePermanent()
.forTable(L3_IF_MAC_DA_TABLE).build();
ops = install ? ops.add(rule) : ops.remove(rule);
} else if (c.type() == Criterion.Type.VLAN_VID) {
VlanIdCriterion v = (VlanIdCriterion) c;
log.debug("adding rule for VLAN: {}", v.vlanId());
.forTable(L3_IF_MAC_DA_TABLE);
}
@Override
protected Builder processVlanFiler(FilteringObjective filt, VlanIdCriterion vlan, PortCriterion port) {
log.debug("adding rule for VLAN: {}", vlan.vlanId());
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
selector.matchVlanId(v.vlanId());
selector.matchInPort(p.port());
selector.matchVlanId(vlan.vlanId());
selector.matchInPort(port.port());
/* Static treatment for VLAN_CIRCUIT_TABLE */
treatment.setVlanPcp(MAX_VLAN_PCP);
treatment.setQueue(0);
treatment.meter(MeterId.meterId(defaultMeterId.id())); /* use default meter (Green) */
treatment.transition(L3_IF_MAC_DA_TABLE);
FlowRule rule = DefaultFlowRule.builder()
.forDevice(deviceId)
return DefaultFlowRule.builder()
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(CONTROLLER_PRIORITY)
.fromApp(applicationId)
.makePermanent()
.forTable(VLAN_CIRCUIT_TABLE).build();
ops = install ? ops.add(rule) : ops.remove(rule);
} else if (c.type() == Criterion.Type.IPV4_DST) {
IPCriterion ip = (IPCriterion) c;
.forTable(VLAN_CIRCUIT_TABLE);
}
@Override
protected Builder processIpFilter(FilteringObjective filt, IPCriterion ip, PortCriterion port) {
log.debug("adding rule for IP: {}", ip.ip());
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
selector.matchEthType(Ethernet.TYPE_IPV4);
selector.matchIPDst(ip.ip());
treatment.transition(LOCAL_TABLE);
FlowRule rule = DefaultFlowRule.builder()
.forDevice(deviceId)
return DefaultFlowRule.builder()
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(HIGHEST_PRIORITY)
.fromApp(applicationId)
.makePermanent()
.forTable(FIB_TABLE).build();
ops = install ? ops.add(rule) : ops.remove(rule);
} else {
log.warn("Driver does not currently process filtering condition"
+ " of type: {}", c.type());
fail(filt, ObjectiveError.UNSUPPORTED);
}
}
// apply filtering flow rules
flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
@Override
public void onSuccess(FlowRuleOperations ops) {
pass(filt);
log.info("Applied filtering rules");
.forTable(FIB_TABLE);
}
@Override
public void onError(FlowRuleOperations ops) {
fail(filt, ObjectiveError.FLOWINSTALLATIONFAILED);
log.info("Failed to apply filtering rules");
}
}));
}
public void initializePipeline() {
processMeterTable(true);
processPortBasedProtoTable(true); /* Table 0 */
......@@ -227,8 +210,8 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline {
processLocalTable(true); /* Table 9 */
}
private void processMeterTable(boolean install) {
/* Green meter : Pass all traffic */
protected void processMeterTable(boolean install) {
//Green meter : Pass all traffic
Band dropBand = DefaultBand.builder()
.ofType(Band.Type.DROP)
.withRate(0xFFFFFFFF) /* Max Rate */
......@@ -242,18 +225,22 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline {
defaultMeterId = meter.id();
}
private void processPortBasedProtoTable(boolean install) {
protected void processPortBasedProtoTable(boolean install) {
/* Default action */
processTableMissGoTo(install, PORT_BASED_PROTO_TABLE, VLAN_CHECK_TABLE);
processTableMissGoTo(install, PORT_BASED_PROTO_TABLE, VLAN_CHECK_TABLE, "Provisioned port-based table");
}
private void processVlanCheckTable(boolean install) {
int table = VLAN_CHECK_TABLE;
protected void processVlanCheckTable(boolean install) {
/* Default action */
processTableMissDrop(install, table);
processTableMissDrop(install, VLAN_CHECK_TABLE, "Provisioned vlantable drop");
processTaggedPackets(install);
}
/* Tagged packets to VLAN_MAC_XLATE */
protected void processTaggedPackets(boolean install) {
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
selector.matchVlanId(VlanId.ANY);
......@@ -267,29 +254,29 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline {
.withPriority(CONTROLLER_PRIORITY)
.fromApp(appId)
.makePermanent()
.forTable(table).build();
processFlowRule(install, rule);
.forTable(VLAN_CHECK_TABLE).build();
processFlowRule(install, rule, "Provisioned vlan table tagged packets");
}
private void processVlanMacXlateTable(boolean install) {
protected void processVlanMacXlateTable(boolean install) {
/* Default action */
processTableMissGoTo(install, VLAN_MAC_XLATE_TABLE, VLAN_CIRCUIT_TABLE);
processTableMissGoTo(install, VLAN_MAC_XLATE_TABLE, VLAN_CIRCUIT_TABLE, "Provisioned vlan mac table");
}
private void processVlanCircuitTable(boolean install) {
protected void processVlanCircuitTable(boolean install) {
/* Default action */
processTableMissDrop(install, VLAN_CIRCUIT_TABLE);
processTableMissDrop(install, VLAN_CIRCUIT_TABLE, "Provisioned vlan circuit");
}
private void processPriorityMapTable(boolean install) {
/* Not required currently */
}
private void processL3IFMacDATable(boolean install) {
protected void processL3IFMacDATable(boolean install) {
int table = L3_IF_MAC_DA_TABLE;
/* Default action */
processTableMissDrop(install, table);
processTableMissDrop(install, table, "Provisioned l3 table drop");
/* Allow MAC broadcast frames on all ports */
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
......@@ -306,15 +293,15 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline {
.fromApp(appId)
.makePermanent()
.forTable(table).build();
processFlowRule(install, rule);
processFlowRule(install, rule, "Provisioned l3 table");
}
private void processEtherTable(boolean install) {
protected void processEtherTable(boolean install) {
int table = ETHER_TABLE;
/* Default action */
processTableMissDrop(install, table);
processTableMissDrop(install, table, "Provisioned ether type table drop");
/* Arp to controller */
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
......@@ -331,7 +318,7 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline {
.fromApp(appId)
.makePermanent()
.forTable(table).build();
processFlowRule(install, rule);
processFlowRule(install, rule, "Provisioned ether type table arp");
/* IP to FIB_TABLE */
selector = DefaultTrafficSelector.builder();
......@@ -348,18 +335,18 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline {
.fromApp(appId)
.makePermanent()
.forTable(table).build();
processFlowRule(install, rule);
processFlowRule(install, rule, "Provisioned ether type table ip");
}
private void processFibTable(boolean install) {
/* Default action */
processTableMissDrop(install, FIB_TABLE);
processTableMissDrop(install, FIB_TABLE, "Provisioned fib drop");
}
private void processLocalTable(boolean install) {
int table = LOCAL_TABLE;
/* Default action */
processTableMissDrop(install, table);
processTableMissDrop(install, table, "Provisioned local table drop");
/* Send all protocols to controller */
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
......@@ -375,62 +362,8 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline {
.fromApp(appId)
.makePermanent()
.forTable(table).build();
processFlowRule(install, rule);
}
/* Init helper: Apply flow rule */
private void processFlowRule(boolean install, FlowRule rule) {
FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
ops = install ? ops.add(rule) : ops.remove(rule);
flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
@Override
public void onSuccess(FlowRuleOperations ops) {
log.info("Flow provision success: " + ops.toString() + ", " + rule.toString());
}
@Override
public void onError(FlowRuleOperations ops) {
log.info("Flow provision error: " + ops.toString() + ", " + rule.toString());
}
}));
processFlowRule(install, rule, "Provisioned ether type table to controller");
}
/* Init helper: Table Miss = Drop */
private void processTableMissDrop(boolean install, int table) {
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
treatment.drop();
FlowRule rule = DefaultFlowRule.builder()
.forDevice(deviceId)
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(DROP_PRIORITY)
.fromApp(appId)
.makePermanent()
.forTable(table).build();
processFlowRule(install, rule);
}
/* Init helper: Table Miss = GoTo */
private void processTableMissGoTo(boolean install, int table, int goTo) {
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
treatment.transition(goTo);
FlowRule rule = DefaultFlowRule.builder()
.forDevice(deviceId)
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(DROP_PRIORITY)
.fromApp(appId)
.makePermanent()
.forTable(table).build();
processFlowRule(install, rule);
}
}
......
/*
* Copyright 2014-2016 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.drivers.corsa;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IPv4;
import org.onlab.packet.VlanId;
import org.onosproject.net.flow.DefaultFlowRule;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flow.criteria.Criterion;
import org.onosproject.net.flow.criteria.IPCriterion;
import org.onosproject.net.flow.criteria.IPProtocolCriterion;
import org.onosproject.net.flowobjective.ForwardingObjective;
import org.onosproject.net.flowobjective.ObjectiveError;
import org.slf4j.Logger;
import java.util.Collection;
import java.util.Collections;
import static org.onosproject.net.flow.FlowRule.Builder;
import static org.slf4j.LoggerFactory.getLogger;
public class CorsaPipelineV39 extends CorsaPipelineV3 {
private final Logger log = getLogger(getClass());
private static final Short NATIVE_VLAN = 4095;
@Override
public void initializePipeline() {
processMeterTable(true); //Meter Table
processPortBasedProtoTable(true);
processVlanCheckTable(true); //Table 1
processVlanMacXlateTable(true); //Table 2
processVlanCircuitTable(true); //Table 3
processL3IFMacDATable(true); //Table 5
processEtherTable(true); //Table 6
//TODO: to be implemented for intents
//processFibTable(true); //Table 7
//processLocalTable(true); //Table 9
}
@Override
protected void processVlanCheckTable(boolean install) {
//FIXME: error
processTableMissGoTo(true, VLAN_CHECK_TABLE, VLAN_MAC_XLATE_TABLE, "Provisioned vlan tagged");
//Tag untagged packets
processUntaggedPackets(install);
}
private void processUntaggedPackets(boolean install) {
deviceService.getPorts(deviceId).forEach(port -> {
if (!port.number().isLogical()) {
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder()
.pushVlan().setVlanId(VlanId.vlanId(NATIVE_VLAN))
.transition(VLAN_MAC_XLATE_TABLE);
TrafficSelector.Builder selector = DefaultTrafficSelector.builder()
.matchVlanId(VlanId.NONE)
.matchInPort(port.number());
Builder rule = DefaultFlowRule.builder()
.forDevice(deviceId)
.withTreatment(treatment.build())
.withSelector(selector.build())
.withPriority(CONTROLLER_PRIORITY)
.fromApp(appId)
.makePermanent()
.forTable(VLAN_CHECK_TABLE);
processFlowRule(install, rule.build(), "Provisioned vlan untagged packet table");
}
});
}
@Override
protected void processVlanCircuitTable(boolean install) {
//Default action
processTableMissDrop(install, VLAN_CIRCUIT_TABLE, "Provisioned vlan circuit table drop");
//FIXME: it should be done only per port based when intent is installed
//Manage untagged packets
processRouterPacket(install);
}
private void processRouterPacket(boolean install) {
deviceService.getPorts(deviceId).forEach(port -> {
if (!port.number().isLogical()) {
TrafficSelector.Builder selector = DefaultTrafficSelector.builder()
.matchVlanId(VlanId.vlanId(NATIVE_VLAN))
.matchInPort(port.number());
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder()
.setVlanPcp((byte) 0)
.setQueue(0)
.meter(defaultMeterId)
.transition(L3_IF_MAC_DA_TABLE);
FlowRule rule = DefaultFlowRule.builder()
.forDevice(deviceId)
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(CONTROLLER_PRIORITY)
.fromApp(appId)
.makePermanent()
.forTable(VLAN_CIRCUIT_TABLE).build();
processFlowRule(install, rule, "Provisioned vlan circuit table");
}
});
}
@Override
protected void processL3IFMacDATable(boolean install) {
int table = L3_IF_MAC_DA_TABLE;
//Default action
processTableMissDrop(install, table, "Provisioned l3 table drop");
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder()
.transition(ETHER_TABLE);
FlowRule rule = DefaultFlowRule.builder()
.forDevice(deviceId)
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(1)
.fromApp(appId)
.makePermanent()
.forTable(table).build();
processFlowRule(install, rule, "Provisioned l3 table");
}
protected void processEtherTable(boolean install) {
//Default action
processTableMissDrop(install, ETHER_TABLE, "Provisioned ether type table drop");
//IP to FIB_TABLE
TrafficSelector.Builder selector = DefaultTrafficSelector.builder()
.matchEthType(Ethernet.TYPE_IPV4);
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder().transition(FIB_TABLE);
FlowRule rule = DefaultFlowRule.builder()
.forDevice(deviceId)
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(CONTROLLER_PRIORITY)
.fromApp(appId)
.makePermanent()
.forTable(ETHER_TABLE).build();
processFlowRule(install, rule, "Provisioned ether type table ip");
}
@Override
protected Collection<FlowRule> processArpTraffic(ForwardingObjective fwd, Builder rule) {
rule.forTable(PORT_BASED_PROTO_TABLE);
rule.withPriority(255);
return Collections.singletonList(rule.build());
}
@Override
protected Collection<FlowRule> processLinkDiscovery(ForwardingObjective fwd, Builder rule) {
rule.forTable(PORT_BASED_PROTO_TABLE);
rule.withPriority(255);
return Collections.singletonList(rule.build());
}
@Override
protected Collection<FlowRule> processIpTraffic(ForwardingObjective fwd, Builder rule) {
IPCriterion ipSrc = (IPCriterion) fwd.selector()
.getCriterion(Criterion.Type.IPV4_SRC);
if (ipSrc != null) {
log.warn("Driver does not currently handle matching Src IP");
fail(fwd, ObjectiveError.UNSUPPORTED);
return Collections.emptySet();
}
IPCriterion ipDst = (IPCriterion) fwd.selector()
.getCriterion(Criterion.Type.IPV4_DST);
if (ipDst != null) {
log.error("Driver handles Dst IP matching as specific forwarding "
+ "objective, not versatile");
fail(fwd, ObjectiveError.UNSUPPORTED);
return Collections.emptySet();
}
IPProtocolCriterion ipProto = (IPProtocolCriterion) fwd.selector()
.getCriterion(Criterion.Type.IP_PROTO);
if (ipProto != null && ipProto.protocol() == IPv4.PROTOCOL_TCP) {
log.warn("Driver automatically punts all packets reaching the "
+ "LOCAL table to the controller");
pass(fwd);
return Collections.emptySet();
}
return Collections.emptySet();
}
}
......@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.driver.handshaker;
package org.onosproject.drivers.corsa;
import org.onosproject.net.meter.MeterId;
import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch;
......
/*
* Copyright 2014-2016 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.drivers.corsa;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IPv4;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.net.flow.DefaultFlowRule;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.FlowRuleOperations;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flow.criteria.Criterion;
import org.onosproject.net.flow.criteria.EthCriterion;
import org.onosproject.net.flow.criteria.IPCriterion;
import org.onosproject.net.flow.criteria.IPProtocolCriterion;
import org.onosproject.net.flow.criteria.PortCriterion;
import org.onosproject.net.flow.criteria.VlanIdCriterion;
import org.onosproject.net.flowobjective.FilteringObjective;
import org.onosproject.net.flowobjective.ForwardingObjective;
import org.onosproject.net.flowobjective.ObjectiveError;
import org.slf4j.Logger;
import java.util.Collection;
import java.util.Collections;
import static org.slf4j.LoggerFactory.getLogger;
/**
* OpenvSwitch emulation of the Corsa pipeline handler.
*/
public class OvsCorsaPipeline extends AbstractCorsaPipeline {
private final Logger log = getLogger(getClass());
protected static final int MAC_TABLE = 0;
protected static final int VLAN_MPLS_TABLE = 1;
protected static final int VLAN_TABLE = 2;
//protected static final int MPLS_TABLE = 3;
protected static final int ETHER_TABLE = 4;
protected static final int COS_MAP_TABLE = 5;
protected static final int FIB_TABLE = 6;
protected static final int LOCAL_TABLE = 9;
@Override
protected Collection<FlowRule> processArpTraffic(ForwardingObjective fwd, FlowRule.Builder rule) {
log.warn("Driver automatically handles ARP packets by punting to controller "
+ " from ETHER table");
pass(fwd);
return Collections.emptyList();
}
@Override
protected Collection<FlowRule> processLinkDiscovery(ForwardingObjective fwd, FlowRule.Builder rule) {
log.warn("Driver currently does not currently handle LLDP packets");
fail(fwd, ObjectiveError.UNSUPPORTED);
return Collections.emptyList();
}
@Override
protected Collection<FlowRule> processIpTraffic(ForwardingObjective fwd, FlowRule.Builder rule) {
IPCriterion ipSrc = (IPCriterion) fwd.selector()
.getCriterion(Criterion.Type.IPV4_SRC);
if (ipSrc != null) {
log.warn("Driver does not currently handle matching Src IP");
fail(fwd, ObjectiveError.UNSUPPORTED);
return Collections.emptySet();
}
IPCriterion ipDst = (IPCriterion) fwd.selector()
.getCriterion(Criterion.Type.IPV4_DST);
if (ipDst != null) {
log.error("Driver handles Dst IP matching as specific forwarding "
+ "objective, not versatile");
fail(fwd, ObjectiveError.UNSUPPORTED);
return Collections.emptySet();
}
IPProtocolCriterion ipProto = (IPProtocolCriterion) fwd.selector()
.getCriterion(Criterion.Type.IP_PROTO);
if (ipProto != null && ipProto.protocol() == IPv4.PROTOCOL_TCP) {
log.warn("Driver automatically punts all packets reaching the "
+ "LOCAL table to the controller");
pass(fwd);
return Collections.emptySet();
}
return Collections.emptySet();
}
@Override
protected FlowRule.Builder processSpecificRoutingRule(FlowRule.Builder rb) {
return rb.forTable(FIB_TABLE);
}
@Override
protected FlowRule.Builder processIpFilter(FilteringObjective filt, IPCriterion ip, PortCriterion port) {
log.debug("adding rule for IP: {}", ip.ip());
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
selector.matchEthType(Ethernet.TYPE_IPV4);
selector.matchIPDst(ip.ip());
treatment.transition(LOCAL_TABLE);
return DefaultFlowRule.builder()
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(HIGHEST_PRIORITY)
.makePermanent()
.forTable(FIB_TABLE);
}
@Override
protected FlowRule.Builder processVlanFiler(FilteringObjective filt, VlanIdCriterion vlan, PortCriterion port) {
log.debug("adding rule for VLAN: {}", vlan.vlanId());
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
selector.matchVlanId(vlan.vlanId());
selector.matchInPort(port.port());
treatment.transition(ETHER_TABLE);
treatment.deferred().popVlan();
return DefaultFlowRule.builder()
.forDevice(deviceId)
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(CONTROLLER_PRIORITY)
.makePermanent()
.forTable(VLAN_TABLE);
}
protected FlowRule.Builder processEthFiler(FilteringObjective filt, EthCriterion eth, PortCriterion port) {
log.debug("adding rule for MAC: {}", eth.mac());
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
selector.matchEthDst(eth.mac());
treatment.transition(VLAN_MPLS_TABLE);
return DefaultFlowRule.builder()
.forDevice(deviceId)
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(CONTROLLER_PRIORITY)
.makePermanent()
.forTable(MAC_TABLE);
}
@Override
protected void initializePipeline() {
processMacTable(true);
processVlanMplsTable(true);
processVlanTable(true);
processEtherTable(true);
processCosTable(true);
processFibTable(true);
processLocalTable(true);
}
private void processMacTable(boolean install) {
TrafficSelector.Builder selector;
TrafficTreatment.Builder treatment;
// Bcast rule
selector = DefaultTrafficSelector.builder();
treatment = DefaultTrafficTreatment.builder();
selector.matchEthDst(MacAddress.BROADCAST);
treatment.transition(VLAN_MPLS_TABLE);
FlowRule rule = DefaultFlowRule.builder()
.forDevice(deviceId)
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(CONTROLLER_PRIORITY)
.fromApp(appId)
.makePermanent()
.forTable(MAC_TABLE).build();
processFlowRule(true, rule, "Provisioned mac table transition");
//Drop rule
processTableMissDrop(true, MAC_TABLE, "Provisioned mac table drop action");
}
protected void processVlanMplsTable(boolean install) {
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment
.builder();
FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
FlowRule rule;
selector.matchVlanId(VlanId.ANY);
treatment.transition(VLAN_TABLE);
rule = DefaultFlowRule.builder()
.forDevice(deviceId)
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(CONTROLLER_PRIORITY)
.fromApp(appId)
.makePermanent()
.forTable(VLAN_MPLS_TABLE).build();
processFlowRule(true, rule, "Provisioned vlan/mpls table");
}
private void processVlanTable(boolean install) {
processTableMissDrop(true, VLAN_TABLE, "Provisioned vlan table");
}
private void processEtherTable(boolean install) {
TrafficSelector.Builder selector = DefaultTrafficSelector.builder()
.matchEthType(Ethernet.TYPE_ARP);
TrafficTreatment.Builder treatment = DefaultTrafficTreatment
.builder()
.punt();
FlowRule rule = DefaultFlowRule.builder()
.forDevice(deviceId)
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(CONTROLLER_PRIORITY)
.fromApp(appId)
.makePermanent()
.forTable(ETHER_TABLE).build();
processFlowRule(true, rule, "Provisioned ether table");
selector = DefaultTrafficSelector.builder()
.matchEthType(Ethernet.TYPE_IPV4);
treatment = DefaultTrafficTreatment.builder()
.transition(COS_MAP_TABLE);
rule = DefaultFlowRule.builder()
.forDevice(deviceId)
.withPriority(CONTROLLER_PRIORITY)
.withSelector(selector.build())
.withTreatment(treatment.build())
.fromApp(appId)
.makePermanent()
.forTable(ETHER_TABLE).build();
processFlowRule(true, rule, "Provisioned ether table");
//Drop rule
processTableMissDrop(true, VLAN_TABLE, "Provisioned ether table");
}
private void processCosTable(boolean install) {
TrafficTreatment.Builder treatment = DefaultTrafficTreatment
.builder()
.transition(FIB_TABLE);
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
FlowRule rule = DefaultFlowRule.builder()
.forDevice(deviceId)
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(DROP_PRIORITY)
.fromApp(appId)
.makePermanent()
.forTable(COS_MAP_TABLE).build();
processFlowRule(true, rule, "Provisioned cos table");
}
private void processFibTable(boolean install) {
processTableMissDrop(true, FIB_TABLE, "Provisioned FIB table");
}
private void processLocalTable(boolean install) {
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment
.builder()
.punt();
FlowRule rule = DefaultFlowRule.builder()
.forDevice(deviceId)
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(CONTROLLER_PRIORITY)
.fromApp(appId)
.makePermanent()
.forTable(LOCAL_TABLE).build();
processFlowRule(true, rule, "Provisioned Local table");
}
}
/*
* Copyright 2014-2016 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Corsa drivers.
*/
package org.onosproject.drivers.corsa;
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2014-2016 Open Networking Laboratory
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<drivers>
<driver name="ovs-corsa" extends="ovs"
manufacturer="Corsa" hwVersion="emulation" swVersion="0.0.0">
<behaviour api="org.onosproject.net.behaviour.Pipeliner"
impl="org.onosproject.drivers.corsa.OvsCorsaPipeline"/>
</driver>
<driver name="corsa"
manufacturer="Corsa" hwVersion="Corsa Element" swVersion="2.3.1">
<behaviour api="org.onosproject.net.behaviour.Pipeliner"
impl="org.onosproject.drivers.corsa.CorsaPipelineV1"/>
<behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver"
impl="org.onosproject.drivers.corsa.CorsaSwitchHandshaker"/>
</driver>
<driver name="corsa-v1"
manufacturer="Corsa" hwVersion="Corsa Element" swVersion="2.3.1">
<behaviour api="org.onosproject.net.behaviour.Pipeliner"
impl="org.onosproject.drivers.corsa.CorsaPipelineV1"/>
<behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver"
impl="org.onosproject.drivers.corsa.CorsaSwitchHandshaker"/>
</driver>
<driver name="corsa-v3"
manufacturer="Corsa" hwVersion="Corsa Element" swVersion="2.3.1">
<behaviour api="org.onosproject.net.behaviour.Pipeliner"
impl="org.onosproject.drivers.corsa.CorsaPipelineV3"/>
<behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver"
impl="org.onosproject.drivers.corsa.CorsaSwitchHandshaker"/>
</driver>
<driver name="corsa-v39"
manufacturer="Corsa" hwVersion="CDP6420-A00" swVersion="corsa-ovs-datapath 1.4.88">
<behaviour api="org.onosproject.net.behaviour.Pipeliner"
impl="org.onosproject.drivers.corsa.CorsaPipelineV39"/>
<behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver"
impl="org.onosproject.drivers.corsa.CorsaSwitchHandshaker"/>
</driver>
</drivers>
\ No newline at end of file
......@@ -39,11 +39,6 @@
<behaviour api="org.onosproject.net.behaviour.MplsQuery"
impl="org.onosproject.driver.query.FullMplsAvailable" />
</driver>
<driver name="ovs-corsa" extends="ovs"
manufacturer="Corsa" hwVersion="emulation" swVersion="0.0.0">
<behaviour api="org.onosproject.net.behaviour.Pipeliner"
impl="org.onosproject.driver.pipeline.OVSCorsaPipeline"/>
</driver>
<!-- Emulation of the spring-open pipeline using a CPqD OF 1.3 software switch.
~ This driver is the default driver assigned to the CPqD switch.
-->
......@@ -67,27 +62,6 @@
<behaviour api="org.onosproject.net.behaviour.LambdaQuery"
impl="org.onosproject.driver.query.LincOELambdaQuery"/>
</driver>
<driver name="corsa"
manufacturer="Corsa" hwVersion="Corsa Element" swVersion="2.3.1">
<behaviour api="org.onosproject.net.behaviour.Pipeliner"
impl="org.onosproject.driver.pipeline.CorsaPipeline"/>
<behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver"
impl="org.onosproject.driver.handshaker.CorsaSwitchHandshaker"/>
</driver>
<driver name="corsa-v1"
manufacturer="Corsa" hwVersion="Corsa Element" swVersion="2.3.1">
<behaviour api="org.onosproject.net.behaviour.Pipeliner"
impl="org.onosproject.driver.pipeline.CorsaPipeline"/>
<behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver"
impl="org.onosproject.driver.handshaker.CorsaSwitchHandshaker"/>
</driver>
<driver name="corsa-v3"
manufacturer="Corsa" hwVersion="Corsa Element" swVersion="2.3.1">
<behaviour api="org.onosproject.net.behaviour.Pipeliner"
impl="org.onosproject.driver.pipeline.CorsaPipelineV3"/>
<behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver"
impl="org.onosproject.driver.handshaker.CorsaSwitchHandshaker"/>
</driver>
<driver name="ofdpa" extends="default"
manufacturer="Broadcom Corp." hwVersion="OF-DPA.*" swVersion="OF-DPA.*">
<behaviour api="org.onosproject.net.behaviour.Pipeliner"
......
......@@ -42,6 +42,7 @@
<module>lumentum</module>
<module>bti</module>
<module>bmv2</module>
<module>corsa</module>
</modules>
<!--<properties>
......