Nicholas Dean
Committed by Brian O'Connor

ONOS-4802 sp2mp intents now apply treatment at the egress switch

Change-Id: Ibdd675f331e522c8b9f1d0e2e9fd5d6b93162fd1
...@@ -39,6 +39,7 @@ public final class LinkCollectionIntent extends ConnectivityIntent { ...@@ -39,6 +39,7 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
39 39
40 private final Set<ConnectPoint> ingressPoints; 40 private final Set<ConnectPoint> ingressPoints;
41 private final Set<ConnectPoint> egressPoints; 41 private final Set<ConnectPoint> egressPoints;
42 + private final boolean egressTreatmentFlag;
42 43
43 /** 44 /**
44 * Creates a new actionable intent capable of funneling the selected 45 * Creates a new actionable intent capable of funneling the selected
...@@ -54,6 +55,7 @@ public final class LinkCollectionIntent extends ConnectivityIntent { ...@@ -54,6 +55,7 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
54 * @param egressPoints egress points 55 * @param egressPoints egress points
55 * @param constraints optional list of constraints 56 * @param constraints optional list of constraints
56 * @param priority priority to use for the flows generated by this intent 57 * @param priority priority to use for the flows generated by this intent
58 + * @param egressTreatment true if treatment should be applied by the egress device
57 * @throws NullPointerException {@code path} is null 59 * @throws NullPointerException {@code path} is null
58 */ 60 */
59 private LinkCollectionIntent(ApplicationId appId, 61 private LinkCollectionIntent(ApplicationId appId,
...@@ -64,11 +66,12 @@ public final class LinkCollectionIntent extends ConnectivityIntent { ...@@ -64,11 +66,12 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
64 Set<ConnectPoint> ingressPoints, 66 Set<ConnectPoint> ingressPoints,
65 Set<ConnectPoint> egressPoints, 67 Set<ConnectPoint> egressPoints,
66 List<Constraint> constraints, 68 List<Constraint> constraints,
67 - int priority) { 69 + int priority, boolean egressTreatment) {
68 super(appId, key, resources(links), selector, treatment, constraints, priority); 70 super(appId, key, resources(links), selector, treatment, constraints, priority);
69 this.links = links; 71 this.links = links;
70 this.ingressPoints = ingressPoints; 72 this.ingressPoints = ingressPoints;
71 this.egressPoints = egressPoints; 73 this.egressPoints = egressPoints;
74 + this.egressTreatmentFlag = egressTreatment;
72 } 75 }
73 76
74 /** 77 /**
...@@ -79,6 +82,7 @@ public final class LinkCollectionIntent extends ConnectivityIntent { ...@@ -79,6 +82,7 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
79 this.links = null; 82 this.links = null;
80 this.ingressPoints = null; 83 this.ingressPoints = null;
81 this.egressPoints = null; 84 this.egressPoints = null;
85 + this.egressTreatmentFlag = false;
82 } 86 }
83 87
84 /** 88 /**
...@@ -100,6 +104,7 @@ public final class LinkCollectionIntent extends ConnectivityIntent { ...@@ -100,6 +104,7 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
100 Set<Link> links; 104 Set<Link> links;
101 Set<ConnectPoint> ingressPoints; 105 Set<ConnectPoint> ingressPoints;
102 Set<ConnectPoint> egressPoints; 106 Set<ConnectPoint> egressPoints;
107 + boolean egressTreatmentFlag;
103 108
104 private Builder() { 109 private Builder() {
105 // Hide constructor 110 // Hide constructor
...@@ -171,6 +176,17 @@ public final class LinkCollectionIntent extends ConnectivityIntent { ...@@ -171,6 +176,17 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
171 return this; 176 return this;
172 } 177 }
173 178
179 + /**
180 + * Sets the intent to apply treatment at the egress rather than the
181 + * ingress.
182 + *
183 + * @param treatmentOnEgress true applies treatment on egress device
184 + * @return this builder
185 + */
186 + public Builder applyTreatmentOnEgress(boolean treatmentOnEgress) {
187 + this.egressTreatmentFlag = treatmentOnEgress;
188 + return this;
189 + }
174 190
175 /** 191 /**
176 * Builds a single point to multi point intent from the 192 * Builds a single point to multi point intent from the
...@@ -189,7 +205,8 @@ public final class LinkCollectionIntent extends ConnectivityIntent { ...@@ -189,7 +205,8 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
189 ingressPoints, 205 ingressPoints,
190 egressPoints, 206 egressPoints,
191 constraints, 207 constraints,
192 - priority 208 + priority,
209 + egressTreatmentFlag
193 ); 210 );
194 } 211 }
195 } 212 }
...@@ -223,6 +240,15 @@ public final class LinkCollectionIntent extends ConnectivityIntent { ...@@ -223,6 +240,15 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
223 return egressPoints; 240 return egressPoints;
224 } 241 }
225 242
243 + /**
244 + * Returns whether treatment should be applied on egress.
245 + *
246 + * @return the egress treatment flag
247 + */
248 + public boolean applyTreatmentOnEgress() {
249 + return egressTreatmentFlag;
250 + }
251 +
226 @Override 252 @Override
227 public String toString() { 253 public String toString() {
228 return MoreObjects.toStringHelper(getClass()) 254 return MoreObjects.toStringHelper(getClass())
...@@ -236,6 +262,7 @@ public final class LinkCollectionIntent extends ConnectivityIntent { ...@@ -236,6 +262,7 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
236 .add("links", links()) 262 .add("links", links())
237 .add("ingress", ingressPoints()) 263 .add("ingress", ingressPoints())
238 .add("egress", egressPoints()) 264 .add("egress", egressPoints())
265 + .add("treatementOnEgress", applyTreatmentOnEgress())
239 .toString(); 266 .toString();
240 } 267 }
241 } 268 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -111,33 +111,57 @@ public class LinkCollectionIntentCompiler implements IntentCompiler<LinkCollecti ...@@ -111,33 +111,57 @@ public class LinkCollectionIntentCompiler implements IntentCompiler<LinkCollecti
111 111
112 private List<FlowRule> createRules(LinkCollectionIntent intent, DeviceId deviceId, 112 private List<FlowRule> createRules(LinkCollectionIntent intent, DeviceId deviceId,
113 Set<PortNumber> inPorts, Set<PortNumber> outPorts) { 113 Set<PortNumber> inPorts, Set<PortNumber> outPorts) {
114 - Set<PortNumber> ingressPorts = intent.ingressPoints().stream()
115 - .filter(point -> point.deviceId().equals(deviceId))
116 - .map(ConnectPoint::port)
117 - .collect(Collectors.toSet());
118 -
119 TrafficTreatment.Builder defaultTreatmentBuilder = DefaultTrafficTreatment.builder(); 114 TrafficTreatment.Builder defaultTreatmentBuilder = DefaultTrafficTreatment.builder();
120 outPorts.stream() 115 outPorts.stream()
121 .forEach(defaultTreatmentBuilder::setOutput); 116 .forEach(defaultTreatmentBuilder::setOutput);
122 - TrafficTreatment defaultTreatment = defaultTreatmentBuilder.build(); 117 + TrafficTreatment outputOnlyTreatment = defaultTreatmentBuilder.build();
123 - 118 + Set<PortNumber> ingressPorts = Collections.emptySet();
124 - TrafficTreatment.Builder ingressTreatmentBuilder = DefaultTrafficTreatment.builder(intent.treatment()); 119 + Set<PortNumber> egressPorts = Collections.emptySet();
125 - outPorts.stream()
126 - .forEach(ingressTreatmentBuilder::setOutput);
127 - TrafficTreatment ingressTreatment = ingressTreatmentBuilder.build();
128 120
129 - TrafficSelector defaultTrafficSelector = applyTreatmentToSelector(intent.selector(), ingressTreatment); 121 + if (!intent.applyTreatmentOnEgress()) {
122 + ingressPorts = intent.ingressPoints().stream()
123 + .filter(point -> point.deviceId().equals(deviceId))
124 + .map(ConnectPoint::port)
125 + .collect(Collectors.toSet());
126 + } else {
127 + egressPorts = intent.egressPoints().stream()
128 + .filter(point -> point.deviceId().equals(deviceId))
129 + .map(ConnectPoint::port)
130 + .collect(Collectors.toSet());
131 + }
130 132
131 List<FlowRule> rules = new ArrayList<>(inPorts.size()); 133 List<FlowRule> rules = new ArrayList<>(inPorts.size());
132 for (PortNumber inPort: inPorts) { 134 for (PortNumber inPort: inPorts) {
133 TrafficSelector.Builder selectorBuilder; 135 TrafficSelector.Builder selectorBuilder;
134 TrafficTreatment treatment; 136 TrafficTreatment treatment;
137 + TrafficTreatment intentTreatment;
138 +
139 + if (!intent.applyTreatmentOnEgress()) {
140 + TrafficTreatment.Builder ingressTreatmentBuilder = DefaultTrafficTreatment.builder(intent.treatment());
141 + outPorts.stream()
142 + .forEach(ingressTreatmentBuilder::setOutput);
143 + intentTreatment = ingressTreatmentBuilder.build();
144 +
135 if (ingressPorts.contains(inPort)) { 145 if (ingressPorts.contains(inPort)) {
136 selectorBuilder = DefaultTrafficSelector.builder(intent.selector()); 146 selectorBuilder = DefaultTrafficSelector.builder(intent.selector());
137 - treatment = ingressTreatment; 147 + treatment = intentTreatment;
148 + } else {
149 + selectorBuilder = applyTreatmentToSelector(intent.selector(), intentTreatment);
150 + treatment = outputOnlyTreatment;
151 + }
152 + } else {
153 + if (outPorts.stream().allMatch(egressPorts::contains)) {
154 + TrafficTreatment.Builder egressTreatmentBuilder =
155 + DefaultTrafficTreatment.builder(intent.treatment());
156 + outPorts.stream()
157 + .forEach(egressTreatmentBuilder::setOutput);
158 +
159 + selectorBuilder = DefaultTrafficSelector.builder(intent.selector());
160 + treatment = egressTreatmentBuilder.build();
138 } else { 161 } else {
139 - selectorBuilder = DefaultTrafficSelector.builder(defaultTrafficSelector); 162 + selectorBuilder = DefaultTrafficSelector.builder(intent.selector());
140 - treatment = defaultTreatment; 163 + treatment = outputOnlyTreatment;
164 + }
141 } 165 }
142 TrafficSelector selector = selectorBuilder.matchInPort(inPort).build(); 166 TrafficSelector selector = selectorBuilder.matchInPort(inPort).build();
143 167
...@@ -155,7 +179,7 @@ public class LinkCollectionIntentCompiler implements IntentCompiler<LinkCollecti ...@@ -155,7 +179,7 @@ public class LinkCollectionIntentCompiler implements IntentCompiler<LinkCollecti
155 return rules; 179 return rules;
156 } 180 }
157 181
158 - private TrafficSelector applyTreatmentToSelector(TrafficSelector selector, TrafficTreatment treatment) { 182 + private TrafficSelector.Builder applyTreatmentToSelector(TrafficSelector selector, TrafficTreatment treatment) {
159 TrafficSelector.Builder defaultSelectorBuilder = DefaultTrafficSelector.builder(selector); 183 TrafficSelector.Builder defaultSelectorBuilder = DefaultTrafficSelector.builder(selector);
160 treatment.allInstructions().forEach(instruction -> { 184 treatment.allInstructions().forEach(instruction -> {
161 switch (instruction.type()) { 185 switch (instruction.type()) {
...@@ -317,6 +341,6 @@ public class LinkCollectionIntentCompiler implements IntentCompiler<LinkCollecti ...@@ -317,6 +341,6 @@ public class LinkCollectionIntentCompiler implements IntentCompiler<LinkCollecti
317 throw new IntentCompilationException("Unknown instruction type"); 341 throw new IntentCompilationException("Unknown instruction type");
318 } 342 }
319 }); 343 });
320 - return defaultSelectorBuilder.build(); 344 + return defaultSelectorBuilder;
321 } 345 }
322 } 346 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -75,6 +75,7 @@ public class SinglePointToMultiPointIntentCompiler ...@@ -75,6 +75,7 @@ public class SinglePointToMultiPointIntentCompiler
75 .ingressPoints(ImmutableSet.of(intent.ingressPoint())) 75 .ingressPoints(ImmutableSet.of(intent.ingressPoint()))
76 .egressPoints(intent.egressPoints()) 76 .egressPoints(intent.egressPoints())
77 .priority(intent.priority()) 77 .priority(intent.priority())
78 + .applyTreatmentOnEgress(true)
78 .constraints(intent.constraints()) 79 .constraints(intent.constraints())
79 .build(); 80 .build();
80 81
......