diff options
Diffstat (limited to 'framework/src/onos/drivers/src/main/java/org/onosproject/driver/pipeline/SpringOpenTTPDell.java')
-rw-r--r-- | framework/src/onos/drivers/src/main/java/org/onosproject/driver/pipeline/SpringOpenTTPDell.java | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/framework/src/onos/drivers/src/main/java/org/onosproject/driver/pipeline/SpringOpenTTPDell.java b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/pipeline/SpringOpenTTPDell.java new file mode 100644 index 00000000..3267d550 --- /dev/null +++ b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/pipeline/SpringOpenTTPDell.java @@ -0,0 +1,200 @@ +/* + * Copyright 2015 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.driver.pipeline; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.onlab.packet.Ethernet; +import org.onlab.packet.MacAddress; +import org.onosproject.core.ApplicationId; +import org.onosproject.net.behaviour.NextGroup; +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.EthCriterion; +import org.onosproject.net.flow.criteria.EthTypeCriterion; +import org.onosproject.net.flow.criteria.IPCriterion; +import org.onosproject.net.flow.criteria.MplsCriterion; +import org.onosproject.net.flow.instructions.Instruction; +import org.onosproject.net.flowobjective.FilteringObjective; +import org.onosproject.net.flowobjective.ForwardingObjective; +import org.onosproject.net.flowobjective.ObjectiveError; +import org.onosproject.net.group.Group; +import org.onosproject.net.group.GroupKey; + +/** + * Spring-open driver implementation for Dell hardware switches. + */ +public class SpringOpenTTPDell extends SpringOpenTTP { + + /* Table IDs to be used for Dell Open Segment Routers*/ + private static final int DELL_TABLE_VLAN = 17; + private static final int DELL_TABLE_TMAC = 18; + private static final int DELL_TABLE_IPV4_UNICAST = 30; + private static final int DELL_TABLE_MPLS = 25; + private static final int DELL_TABLE_ACL = 40; + + //TODO: Store this info in the distributed store. + private MacAddress deviceTMac = null; + + public SpringOpenTTPDell() { + super(); + vlanTableId = DELL_TABLE_VLAN; + tmacTableId = DELL_TABLE_TMAC; + ipv4UnicastTableId = DELL_TABLE_IPV4_UNICAST; + mplsTableId = DELL_TABLE_MPLS; + aclTableId = DELL_TABLE_ACL; + } + + @Override + protected void setTableMissEntries() { + // No need to set table-miss-entries in Dell switches + return; + } + + @Override + //Dell switches need ETH_DST based match condition in all IP table entries. + //So this method overrides the default spring-open behavior and adds + //ETH_DST match condition while pushing IP table flow rules + protected Collection<FlowRule> processSpecific(ForwardingObjective fwd) { + log.debug("Processing specific"); + TrafficSelector selector = fwd.selector(); + EthTypeCriterion ethType = (EthTypeCriterion) selector + .getCriterion(Criterion.Type.ETH_TYPE); + if ((ethType == null) || + (ethType.ethType().toShort() != Ethernet.TYPE_IPV4) && + (ethType.ethType().toShort() != Ethernet.MPLS_UNICAST)) { + log.debug("processSpecific: Unsupported " + + "forwarding objective criteraia"); + fail(fwd, ObjectiveError.UNSUPPORTED); + return Collections.emptySet(); + } + + TrafficSelector.Builder filteredSelectorBuilder = + DefaultTrafficSelector.builder(); + int forTableId = -1; + if (ethType.ethType().toShort() == Ethernet.TYPE_IPV4) { + if (deviceTMac == null) { + log.debug("processSpecific: ETH_DST filtering " + + "objective is not set which is required " + + "before sending a IPv4 forwarding objective"); + //TODO: Map the error to more appropriate error code. + fail(fwd, ObjectiveError.DEVICEMISSING); + return Collections.emptySet(); + } + filteredSelectorBuilder = filteredSelectorBuilder + .matchEthType(Ethernet.TYPE_IPV4) + .matchEthDst(deviceTMac) + .matchIPDst(((IPCriterion) selector + .getCriterion(Criterion.Type.IPV4_DST)) + .ip()); + forTableId = ipv4UnicastTableId; + log.debug("processing IPv4 specific forwarding objective"); + } else { + filteredSelectorBuilder = filteredSelectorBuilder + .matchEthType(Ethernet.MPLS_UNICAST) + .matchMplsLabel(((MplsCriterion) + selector.getCriterion(Criterion.Type.MPLS_LABEL)).label()); + //TODO: Add Match for BoS + //if (selector.getCriterion(Criterion.Type.MPLS_BOS) != null) { + //} + forTableId = mplsTableId; + log.debug("processing MPLS specific forwarding objective"); + } + + TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment + .builder(); + if (fwd.treatment() != null) { + for (Instruction i : fwd.treatment().allInstructions()) { + treatmentBuilder.add(i); + } + } + + if (fwd.nextId() != null) { + NextGroup next = flowObjectiveStore.getNextGroup(fwd.nextId()); + + if (next != null) { + GroupKey key = appKryo.deserialize(next.data()); + + Group group = groupService.getGroup(deviceId, key); + + if (group == null) { + log.warn("The group left!"); + fail(fwd, ObjectiveError.GROUPMISSING); + return Collections.emptySet(); + } + treatmentBuilder.group(group.id()); + log.debug("Adding OUTGROUP action"); + } else { + log.warn("processSpecific: No associated next objective object"); + fail(fwd, ObjectiveError.GROUPMISSING); + return Collections.emptySet(); + } + } + + TrafficSelector filteredSelector = filteredSelectorBuilder.build(); + TrafficTreatment treatment = treatmentBuilder.transition(aclTableId) + .build(); + + FlowRule.Builder ruleBuilder = DefaultFlowRule.builder() + .fromApp(fwd.appId()).withPriority(fwd.priority()) + .forDevice(deviceId).withSelector(filteredSelector) + .withTreatment(treatment); + + if (fwd.permanent()) { + ruleBuilder.makePermanent(); + } else { + ruleBuilder.makeTemporary(fwd.timeout()); + } + + ruleBuilder.forTable(forTableId); + return Collections.singletonList(ruleBuilder.build()); + + } + + @Override + //Dell switches need ETH_DST based match condition in all IP table entries. + //So while processing the ETH_DST based filtering objective, store + //the device MAC to be used locally to use it while pushing the IP rules. + protected List<FlowRule> processEthDstFilter(Criterion c, + FilteringObjective filt, + ApplicationId applicationId) { + // Store device termination Mac to be used in IP flow entries + EthCriterion e = (EthCriterion) c; + deviceTMac = e.mac(); + + log.debug("For now not adding any TMAC rules " + + "into Dell switches as it is ignoring"); + + return Collections.emptyList(); + } + + @Override + protected List<FlowRule> processVlanIdFilter(Criterion c, + FilteringObjective filt, + ApplicationId applicationId) { + log.debug("For now not adding any VLAN rules " + + "into Dell switches as it is ignoring"); + + return Collections.emptyList(); + } +}
\ No newline at end of file |