Add support for vlan based intents in the Corsa driver
Changes:
- Improves processSpecific in AbstractCorsaPipeline in order to support
Intents without an explicit match on the Ethertype;
- Implements vlan based circuits in CorsaPipelineV3 through the management
of the FwdObjective without Treatment;
- Distinguish Groups from simple actions;
- Corsa group are identified using the actions of the treatment;
- handling of the pending next similar to DefaultSingleTablePipeline
Change-Id: Iff0f70d56c64193524c6640f31ffb3f5629499dc
diff --git a/drivers/corsa/src/main/java/org/onosproject/drivers/corsa/CorsaPipelineV3.java b/drivers/corsa/src/main/java/org/onosproject/drivers/corsa/CorsaPipelineV3.java
index 10e3f0b..b1e15b2 100644
--- a/drivers/corsa/src/main/java/org/onosproject/drivers/corsa/CorsaPipelineV3.java
+++ b/drivers/corsa/src/main/java/org/onosproject/drivers/corsa/CorsaPipelineV3.java
@@ -30,9 +30,12 @@
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.Instruction;
import org.onosproject.net.flow.instructions.L2ModificationInstruction;
import org.onosproject.net.flowobjective.FilteringObjective;
import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.NextObjective;
+import org.onosproject.net.flowobjective.ObjectiveError;
import org.onosproject.net.meter.Band;
import org.onosproject.net.meter.DefaultBand;
import org.onosproject.net.meter.DefaultMeterRequest;
@@ -69,9 +72,11 @@
protected MeterId defaultMeterId = null;
@Override
- protected TrafficTreatment processNextTreatment(TrafficTreatment treatment) {
+ protected CorsaTrafficTreatment processNextTreatment(TrafficTreatment treatment) {
TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder();
+
+
treatment.immediate().stream()
.filter(i -> {
switch (i.type()) {
@@ -87,7 +92,48 @@
return false;
}
}).forEach(i -> tb.add(i));
- return tb.build();
+
+ TrafficTreatment t = tb.build();
+
+
+ boolean isPresentModVlanId = false;
+ boolean isPresentModEthSrc = false;
+ boolean isPresentModEthDst = false;
+ boolean isPresentOutpuPort = false;
+
+ for (Instruction instruction : t.immediate()) {
+ switch (instruction.type()) {
+ case L2MODIFICATION:
+ L2ModificationInstruction l2i = (L2ModificationInstruction) instruction;
+ if (l2i instanceof L2ModificationInstruction.ModVlanIdInstruction) {
+ isPresentModVlanId = true;
+ }
+
+ if (l2i instanceof L2ModificationInstruction.ModEtherInstruction) {
+ L2ModificationInstruction.L2SubType subType = l2i.subtype();
+ if (subType.equals(L2ModificationInstruction.L2SubType.ETH_SRC)) {
+ isPresentModEthSrc = true;
+ } else if (subType.equals(L2ModificationInstruction.L2SubType.ETH_DST)) {
+ isPresentModEthDst = true;
+ }
+ }
+ case OUTPUT:
+ isPresentOutpuPort = true;
+ default:
+ }
+ }
+ CorsaTrafficTreatmentType type = CorsaTrafficTreatmentType.ACTIONS;
+ /**
+ * This represents the allowed group for CorsaPipelinev3
+ */
+ if (isPresentModVlanId &&
+ isPresentModEthSrc &&
+ isPresentModEthDst &&
+ isPresentOutpuPort) {
+ type = CorsaTrafficTreatmentType.GROUP;
+ }
+ CorsaTrafficTreatment corsaTreatment = new CorsaTrafficTreatment(type, t);
+ return corsaTreatment;
}
@Override
@@ -115,9 +161,37 @@
.withPriority(fwd.priority())
.forDevice(deviceId)
.withSelector(filteredSelector)
- .withTreatment(fwd.treatment())
.forTable(VLAN_CIRCUIT_TABLE);
+ if (fwd.treatment() != null) {
+ ruleBuilder.withTreatment(fwd.treatment());
+ } else {
+ if (fwd.nextId() != null) {
+ NextObjective nextObjective = pendingNext.getIfPresent(fwd.nextId());
+ if (nextObjective != null) {
+ pendingNext.invalidate(fwd.nextId());
+ TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder()
+ .setVlanPcp((byte) 0)
+ .setQueue(0)
+ .meter(defaultMeterId);
+ nextObjective.next().forEach(trafficTreatment -> {
+ trafficTreatment.allInstructions().forEach(instruction -> {
+ treatment.add(instruction);
+ });
+ });
+ ruleBuilder.withTreatment(treatment.build());
+ } else {
+ log.warn("The group left!");
+ fwd.context().ifPresent(c -> c.onError(fwd, ObjectiveError.GROUPMISSING));
+ return ImmutableSet.of();
+ }
+ } else {
+ log.warn("Missing NextObjective ID for ForwardingObjective {}", fwd.id());
+ fail(fwd, ObjectiveError.BADPARAMS);
+ return ImmutableSet.of();
+ }
+ }
+
if (fwd.permanent()) {
ruleBuilder.makePermanent();
} else {