SEBA-816 Multi-tcont support by OltPipeline
Change-Id: I9df0df7c2c6f41bbb35effc6feef640698d19e08
(cherry picked from commit fe93448daca9013a77fbc1cb3b38b42d8d433437)
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/OltPipeline.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/OltPipeline.java
index a54a140..5597d8b 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/OltPipeline.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/OltPipeline.java
@@ -27,6 +27,7 @@
import org.onlab.packet.EthType;
import org.onlab.packet.IPv4;
import org.onlab.packet.IPv6;
+import org.onlab.packet.IpPrefix;
import org.onlab.packet.VlanId;
import org.onlab.util.KryoNamespace;
import org.onosproject.core.ApplicationId;
@@ -78,14 +79,14 @@
import org.onosproject.store.service.StorageService;
import org.slf4j.Logger;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
-import java.util.Arrays;
-import java.util.Objects;
import static org.slf4j.LoggerFactory.getLogger;
@@ -364,13 +365,15 @@
TrafficTreatment treatment =
buildTreatment(Instructions.createGroup(group.id()));
+ TrafficSelector.Builder selectorBuilder = buildIpv4SelectorForMulticast(fwd);
+
FlowRule rule = DefaultFlowRule.builder()
.fromApp(fwd.appId())
.forDevice(deviceId)
.forTable(0)
.makePermanent()
.withPriority(fwd.priority())
- .withSelector(fwd.selector())
+ .withSelector(selectorBuilder.build())
.withTreatment(treatment)
.build();
@@ -394,6 +397,39 @@
}
+ private TrafficSelector.Builder buildIpv4SelectorForMulticast(ForwardingObjective fwd) {
+ TrafficSelector.Builder builderToUpdate = DefaultTrafficSelector.builder();
+
+ Optional<Criterion> vlanIdCriterion = readFromSelector(fwd.meta(), Criterion.Type.VLAN_VID);
+ if (vlanIdCriterion.isPresent()) {
+ VlanId assignedVlan = ((VlanIdCriterion) vlanIdCriterion.get()).vlanId();
+ builderToUpdate.matchVlanId(assignedVlan);
+ }
+
+ Optional<Criterion> ethTypeCriterion = readFromSelector(fwd.selector(), Criterion.Type.ETH_TYPE);
+ if (ethTypeCriterion.isPresent()) {
+ EthType ethType = ((EthTypeCriterion) ethTypeCriterion.get()).ethType();
+ builderToUpdate.matchEthType(ethType.toShort());
+ }
+
+ Optional<Criterion> ipv4DstCriterion = readFromSelector(fwd.selector(), Criterion.Type.IPV4_DST);
+ if (ipv4DstCriterion.isPresent()) {
+ IpPrefix ipv4Dst = ((IPCriterion) ipv4DstCriterion.get()).ip();
+ builderToUpdate.matchIPDst(ipv4Dst);
+ }
+
+ return builderToUpdate;
+ }
+
+ static Optional<Criterion> readFromSelector(TrafficSelector selector, Criterion.Type type) {
+ if (selector == null) {
+ return Optional.empty();
+ }
+ Criterion criterion = selector.getCriterion(type);
+ return (criterion == null)
+ ? Optional.empty() : Optional.of(criterion);
+ }
+
private boolean checkForMulticast(ForwardingObjective fwd) {
IPCriterion ip = (IPCriterion) filterForCriterion(fwd.selector().criteria(),
@@ -452,8 +488,10 @@
TrafficSelector selector = fwd.selector();
Criterion outerVlan = selector.getCriterion(Criterion.Type.VLAN_VID);
+ Criterion outerPbit = selector.getCriterion(Criterion.Type.VLAN_PCP);
Criterion innerVlanCriterion = selector.getCriterion(Criterion.Type.INNER_VLAN_VID);
Criterion inport = selector.getCriterion(Criterion.Type.IN_PORT);
+ Criterion dstMac = selector.getCriterion(Criterion.Type.ETH_DST);
if (outerVlan == null || innerVlanCriterion == null || inport == null) {
log.error("Forwarding objective is underspecified: {}", fwd);
@@ -470,7 +508,7 @@
// Maybe - find a better way to solve the above problem
Criterion metadata = Criteria.matchMetadata(innerVlan.toShort());
- TrafficSelector outerSelector = buildSelector(inport, metadata, outerVlan);
+ TrafficSelector outerSelector = buildSelector(inport, metadata, outerVlan, outerPbit, dstMac);
if (innerVlan.toShort() == VlanId.ANY_VALUE) {
installDownstreamRulesForAnyVlan(fwd, output, outerSelector, buildSelector(inport,
@@ -499,10 +537,30 @@
innerTreatment = (buildTreatment(popAndRewrite.getLeft(), fetchMeter(fwd),
writeMetadataIncludingOnlyTp(fwd), output));
} else {
- innerTreatment = (buildTreatment(popAndRewrite.getLeft(), popAndRewrite.getRight(),
+ innerTreatment = (buildTreatment(popAndRewrite.getRight(),
fetchMeter(fwd), writeMetadataIncludingOnlyTp(fwd), output));
}
+ List<Instruction> setVlanPcps = findL2Instructions(L2ModificationInstruction.L2SubType.VLAN_PCP,
+ fwd.treatment().allInstructions());
+
+ Instruction innerPbitSet = null;
+
+ if (setVlanPcps != null && !setVlanPcps.isEmpty()) {
+ innerPbitSet = setVlanPcps.get(0);
+ }
+
+ VlanId remarkInnerVlan = null;
+ Optional<Criterion> vlanIdCriterion = readFromSelector(innerSelector, Criterion.Type.VLAN_VID);
+ if (vlanIdCriterion.isPresent()) {
+ remarkInnerVlan = ((VlanIdCriterion) vlanIdCriterion.get()).vlanId();
+ }
+
+ Instruction modVlanId = null;
+ if (innerPbitSet != null) {
+ modVlanId = Instructions.modVlanId(remarkInnerVlan);
+ }
+
//match: in port (nni), s-tag
//action: pop vlan (s-tag), write metadata, go to table 1, meter
FlowRule.Builder outer = DefaultFlowRule.builder()
@@ -511,8 +569,8 @@
.makePermanent()
.withPriority(fwd.priority())
.withSelector(outerSelector)
- .withTreatment(buildTreatment(popAndRewrite.getLeft(), fetchMeter(fwd), fetchWriteMetadata(fwd),
- Instructions.transition(QQ_TABLE)));
+ .withTreatment(buildTreatment(popAndRewrite.getLeft(), modVlanId,
+ innerPbitSet, fetchMeter(fwd), fetchWriteMetadata(fwd), Instructions.transition(QQ_TABLE)));
//match: in port (nni), c-tag
//action: immediate: write metadata and pop, meter, output
@@ -588,13 +646,25 @@
Pair<Instruction, Instruction> innerPair,
Pair<Instruction, Instruction> outerPair, Boolean noneValueVlanStatus) {
+ List<Instruction> setVlanPcps = findL2Instructions(L2ModificationInstruction.L2SubType.VLAN_PCP,
+ fwd.treatment().allInstructions());
+
+ Instruction innerPbitSet = null;
+ Instruction outerPbitSet = null;
+
+ if (setVlanPcps != null && !setVlanPcps.isEmpty()) {
+ innerPbitSet = setVlanPcps.get(0);
+ outerPbitSet = setVlanPcps.get(1);
+ }
+
TrafficTreatment innerTreatment;
if (noneValueVlanStatus) {
innerTreatment = buildTreatment(innerPair.getLeft(), innerPair.getRight(), fetchMeter(fwd),
- fetchWriteMetadata(fwd), Instructions.transition(QQ_TABLE));
+ fetchWriteMetadata(fwd), innerPbitSet,
+ Instructions.transition(QQ_TABLE));
} else {
innerTreatment = buildTreatment(innerPair.getRight(), fetchMeter(fwd), fetchWriteMetadata(fwd),
- Instructions.transition(QQ_TABLE));
+ innerPbitSet, Instructions.transition(QQ_TABLE));
}
//match: in port, vlanId (0 or None)
@@ -623,9 +693,17 @@
.forTable(QQ_TABLE)
.makePermanent()
.withPriority(fwd.priority())
- .withSelector(buildSelector(inPort, Criteria.matchVlanId(cVlanId)))
.withTreatment(buildTreatment(outerPair.getLeft(), outerPair.getRight(),
- fetchMeter(fwd), writeMetadataIncludingOnlyTp(fwd), output));
+ fetchMeter(fwd), writeMetadataIncludingOnlyTp(fwd),
+ outerPbitSet, output));
+
+ if (innerPbitSet != null) {
+ byte innerPbit = ((L2ModificationInstruction.ModVlanPcpInstruction)
+ innerPbitSet).vlanPcp();
+ outer.withSelector(buildSelector(inPort, Criteria.matchVlanId(cVlanId), Criteria.matchVlanPcp(innerPbit)));
+ } else {
+ outer.withSelector(buildSelector(inPort, Criteria.matchVlanId(cVlanId)));
+ }
applyRules(fwd, inner, outer);
}
@@ -761,21 +839,21 @@
private List<Pair<Instruction, Instruction>> findVlanOps(List<Instruction> instructions,
L2ModificationInstruction.L2SubType type) {
- List<Instruction> vlanPushs = findL2Instructions(
+ List<Instruction> vlanOperations = findL2Instructions(
type,
instructions);
List<Instruction> vlanSets = findL2Instructions(
L2ModificationInstruction.L2SubType.VLAN_ID,
instructions);
- if (vlanPushs.size() != vlanSets.size()) {
+ if (vlanOperations.size() != vlanSets.size()) {
return ImmutableList.of();
}
List<Pair<Instruction, Instruction>> pairs = Lists.newArrayList();
- for (int i = 0; i < vlanPushs.size(); i++) {
- pairs.add(new ImmutablePair<>(vlanPushs.get(i), vlanSets.get(i)));
+ for (int i = 0; i < vlanOperations.size(); i++) {
+ pairs.add(new ImmutablePair<>(vlanOperations.get(i), vlanSets.get(i)));
}
return pairs;
}
@@ -810,7 +888,12 @@
Instruction meter = filter.meta().metered();
Instruction writeMetadata = filter.meta().writeMetadata();
- TrafficSelector selector = buildSelector(filter.key(), ethType, ipProto);
+ // cTag
+ VlanIdCriterion vlanId = (VlanIdCriterion) filterForCriterion(filter.conditions(),
+ Criterion.Type.VLAN_VID);
+ Criterion cTagPriority = filterForCriterion(filter.conditions(), Criterion.Type.VLAN_PCP);
+
+ TrafficSelector selector = buildSelector(filter.key(), ethType, ipProto, vlanId, cTagPriority);
TrafficTreatment treatment = buildTreatment(output, meter, writeMetadata);
buildAndApplyRule(filter, selector, treatment);
}
@@ -824,7 +907,10 @@
Instruction meter = filter.meta().metered();
Instruction writeMetadata = filter.meta().writeMetadata();
- TrafficSelector selector = buildSelector(filter.key(), ethType, ipProto, udpSrcPort, udpDstPort);
+ VlanIdCriterion vlanId = (VlanIdCriterion)
+ filterForCriterion(filter.conditions(), Criterion.Type.VLAN_VID);
+
+ TrafficSelector selector = buildSelector(filter.key(), ethType, ipProto, udpSrcPort, udpDstPort, vlanId);
TrafficTreatment treatment = buildTreatment(output, meter, writeMetadata);
buildAndApplyRule(filter, selector, treatment);
}