ONOS-4802 sp2mp intents now apply treatment at the egress switch
Change-Id: Ibdd675f331e522c8b9f1d0e2e9fd5d6b93162fd1
diff --git a/core/api/src/main/java/org/onosproject/net/intent/LinkCollectionIntent.java b/core/api/src/main/java/org/onosproject/net/intent/LinkCollectionIntent.java
index f7ca15c..f72354d 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/LinkCollectionIntent.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/LinkCollectionIntent.java
@@ -39,6 +39,7 @@
private final Set<ConnectPoint> ingressPoints;
private final Set<ConnectPoint> egressPoints;
+ private final boolean egressTreatmentFlag;
/**
* Creates a new actionable intent capable of funneling the selected
@@ -54,21 +55,23 @@
* @param egressPoints egress points
* @param constraints optional list of constraints
* @param priority priority to use for the flows generated by this intent
+ * @param egressTreatment true if treatment should be applied by the egress device
* @throws NullPointerException {@code path} is null
*/
private LinkCollectionIntent(ApplicationId appId,
- Key key,
- TrafficSelector selector,
- TrafficTreatment treatment,
- Set<Link> links,
- Set<ConnectPoint> ingressPoints,
- Set<ConnectPoint> egressPoints,
- List<Constraint> constraints,
- int priority) {
+ Key key,
+ TrafficSelector selector,
+ TrafficTreatment treatment,
+ Set<Link> links,
+ Set<ConnectPoint> ingressPoints,
+ Set<ConnectPoint> egressPoints,
+ List<Constraint> constraints,
+ int priority, boolean egressTreatment) {
super(appId, key, resources(links), selector, treatment, constraints, priority);
this.links = links;
this.ingressPoints = ingressPoints;
this.egressPoints = egressPoints;
+ this.egressTreatmentFlag = egressTreatment;
}
/**
@@ -79,6 +82,7 @@
this.links = null;
this.ingressPoints = null;
this.egressPoints = null;
+ this.egressTreatmentFlag = false;
}
/**
@@ -100,6 +104,7 @@
Set<Link> links;
Set<ConnectPoint> ingressPoints;
Set<ConnectPoint> egressPoints;
+ boolean egressTreatmentFlag;
private Builder() {
// Hide constructor
@@ -171,6 +176,17 @@
return this;
}
+ /**
+ * Sets the intent to apply treatment at the egress rather than the
+ * ingress.
+ *
+ * @param treatmentOnEgress true applies treatment on egress device
+ * @return this builder
+ */
+ public Builder applyTreatmentOnEgress(boolean treatmentOnEgress) {
+ this.egressTreatmentFlag = treatmentOnEgress;
+ return this;
+ }
/**
* Builds a single point to multi point intent from the
@@ -189,7 +205,8 @@
ingressPoints,
egressPoints,
constraints,
- priority
+ priority,
+ egressTreatmentFlag
);
}
}
@@ -223,6 +240,15 @@
return egressPoints;
}
+ /**
+ * Returns whether treatment should be applied on egress.
+ *
+ * @return the egress treatment flag
+ */
+ public boolean applyTreatmentOnEgress() {
+ return egressTreatmentFlag;
+ }
+
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
@@ -236,6 +262,7 @@
.add("links", links())
.add("ingress", ingressPoints())
.add("egress", egressPoints())
+ .add("treatementOnEgress", applyTreatmentOnEgress())
.toString();
}
-}
+}
\ No newline at end of file
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentCompiler.java
index d582f6e..9fd7b12 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentCompiler.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentCompiler.java
@@ -111,51 +111,75 @@
private List<FlowRule> createRules(LinkCollectionIntent intent, DeviceId deviceId,
Set<PortNumber> inPorts, Set<PortNumber> outPorts) {
- Set<PortNumber> ingressPorts = intent.ingressPoints().stream()
- .filter(point -> point.deviceId().equals(deviceId))
- .map(ConnectPoint::port)
- .collect(Collectors.toSet());
-
TrafficTreatment.Builder defaultTreatmentBuilder = DefaultTrafficTreatment.builder();
outPorts.stream()
.forEach(defaultTreatmentBuilder::setOutput);
- TrafficTreatment defaultTreatment = defaultTreatmentBuilder.build();
+ TrafficTreatment outputOnlyTreatment = defaultTreatmentBuilder.build();
+ Set<PortNumber> ingressPorts = Collections.emptySet();
+ Set<PortNumber> egressPorts = Collections.emptySet();
- TrafficTreatment.Builder ingressTreatmentBuilder = DefaultTrafficTreatment.builder(intent.treatment());
- outPorts.stream()
- .forEach(ingressTreatmentBuilder::setOutput);
- TrafficTreatment ingressTreatment = ingressTreatmentBuilder.build();
-
- TrafficSelector defaultTrafficSelector = applyTreatmentToSelector(intent.selector(), ingressTreatment);
+ if (!intent.applyTreatmentOnEgress()) {
+ ingressPorts = intent.ingressPoints().stream()
+ .filter(point -> point.deviceId().equals(deviceId))
+ .map(ConnectPoint::port)
+ .collect(Collectors.toSet());
+ } else {
+ egressPorts = intent.egressPoints().stream()
+ .filter(point -> point.deviceId().equals(deviceId))
+ .map(ConnectPoint::port)
+ .collect(Collectors.toSet());
+ }
List<FlowRule> rules = new ArrayList<>(inPorts.size());
for (PortNumber inPort: inPorts) {
TrafficSelector.Builder selectorBuilder;
TrafficTreatment treatment;
- if (ingressPorts.contains(inPort)) {
- selectorBuilder = DefaultTrafficSelector.builder(intent.selector());
- treatment = ingressTreatment;
+ TrafficTreatment intentTreatment;
+
+ if (!intent.applyTreatmentOnEgress()) {
+ TrafficTreatment.Builder ingressTreatmentBuilder = DefaultTrafficTreatment.builder(intent.treatment());
+ outPorts.stream()
+ .forEach(ingressTreatmentBuilder::setOutput);
+ intentTreatment = ingressTreatmentBuilder.build();
+
+ if (ingressPorts.contains(inPort)) {
+ selectorBuilder = DefaultTrafficSelector.builder(intent.selector());
+ treatment = intentTreatment;
+ } else {
+ selectorBuilder = applyTreatmentToSelector(intent.selector(), intentTreatment);
+ treatment = outputOnlyTreatment;
+ }
} else {
- selectorBuilder = DefaultTrafficSelector.builder(defaultTrafficSelector);
- treatment = defaultTreatment;
+ if (outPorts.stream().allMatch(egressPorts::contains)) {
+ TrafficTreatment.Builder egressTreatmentBuilder =
+ DefaultTrafficTreatment.builder(intent.treatment());
+ outPorts.stream()
+ .forEach(egressTreatmentBuilder::setOutput);
+
+ selectorBuilder = DefaultTrafficSelector.builder(intent.selector());
+ treatment = egressTreatmentBuilder.build();
+ } else {
+ selectorBuilder = DefaultTrafficSelector.builder(intent.selector());
+ treatment = outputOnlyTreatment;
+ }
}
TrafficSelector selector = selectorBuilder.matchInPort(inPort).build();
FlowRule rule = DefaultFlowRule.builder()
- .forDevice(deviceId)
- .withSelector(selector)
- .withTreatment(treatment)
- .withPriority(intent.priority())
- .fromApp(appId)
- .makePermanent()
- .build();
+ .forDevice(deviceId)
+ .withSelector(selector)
+ .withTreatment(treatment)
+ .withPriority(intent.priority())
+ .fromApp(appId)
+ .makePermanent()
+ .build();
rules.add(rule);
}
return rules;
}
- private TrafficSelector applyTreatmentToSelector(TrafficSelector selector, TrafficTreatment treatment) {
+ private TrafficSelector.Builder applyTreatmentToSelector(TrafficSelector selector, TrafficTreatment treatment) {
TrafficSelector.Builder defaultSelectorBuilder = DefaultTrafficSelector.builder(selector);
treatment.allInstructions().forEach(instruction -> {
switch (instruction.type()) {
@@ -317,6 +341,6 @@
throw new IntentCompilationException("Unknown instruction type");
}
});
- return defaultSelectorBuilder.build();
+ return defaultSelectorBuilder;
}
-}
+}
\ No newline at end of file
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/SinglePointToMultiPointIntentCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/SinglePointToMultiPointIntentCompiler.java
index 2508654..0da2194 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/SinglePointToMultiPointIntentCompiler.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/SinglePointToMultiPointIntentCompiler.java
@@ -75,9 +75,10 @@
.ingressPoints(ImmutableSet.of(intent.ingressPoint()))
.egressPoints(intent.egressPoints())
.priority(intent.priority())
+ .applyTreatmentOnEgress(true)
.constraints(intent.constraints())
.build();
return Collections.singletonList(result);
}
-}
+}
\ No newline at end of file