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,21 +55,23 @@ public final class LinkCollectionIntent extends ConnectivityIntent { ...@@ -54,21 +55,23 @@ 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,
60 - Key key, 62 + Key key,
61 - TrafficSelector selector, 63 + TrafficSelector selector,
62 - TrafficTreatment treatment, 64 + TrafficTreatment treatment,
63 - Set<Link> links, 65 + Set<Link> links,
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,51 +111,75 @@ public class LinkCollectionIntentCompiler implements IntentCompiler<LinkCollecti ...@@ -111,51 +111,75 @@ 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;
135 - if (ingressPorts.contains(inPort)) { 137 + TrafficTreatment intentTreatment;
136 - selectorBuilder = DefaultTrafficSelector.builder(intent.selector()); 138 +
137 - treatment = ingressTreatment; 139 + if (!intent.applyTreatmentOnEgress()) {
140 + TrafficTreatment.Builder ingressTreatmentBuilder = DefaultTrafficTreatment.builder(intent.treatment());
141 + outPorts.stream()
142 + .forEach(ingressTreatmentBuilder::setOutput);
143 + intentTreatment = ingressTreatmentBuilder.build();
144 +
145 + if (ingressPorts.contains(inPort)) {
146 + selectorBuilder = DefaultTrafficSelector.builder(intent.selector());
147 + treatment = intentTreatment;
148 + } else {
149 + selectorBuilder = applyTreatmentToSelector(intent.selector(), intentTreatment);
150 + treatment = outputOnlyTreatment;
151 + }
138 } else { 152 } else {
139 - selectorBuilder = DefaultTrafficSelector.builder(defaultTrafficSelector); 153 + if (outPorts.stream().allMatch(egressPorts::contains)) {
140 - treatment = defaultTreatment; 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();
161 + } else {
162 + selectorBuilder = DefaultTrafficSelector.builder(intent.selector());
163 + treatment = outputOnlyTreatment;
164 + }
141 } 165 }
142 TrafficSelector selector = selectorBuilder.matchInPort(inPort).build(); 166 TrafficSelector selector = selectorBuilder.matchInPort(inPort).build();
143 167
144 FlowRule rule = DefaultFlowRule.builder() 168 FlowRule rule = DefaultFlowRule.builder()
145 - .forDevice(deviceId) 169 + .forDevice(deviceId)
146 - .withSelector(selector) 170 + .withSelector(selector)
147 - .withTreatment(treatment) 171 + .withTreatment(treatment)
148 - .withPriority(intent.priority()) 172 + .withPriority(intent.priority())
149 - .fromApp(appId) 173 + .fromApp(appId)
150 - .makePermanent() 174 + .makePermanent()
151 - .build(); 175 + .build();
152 rules.add(rule); 176 rules.add(rule);
153 } 177 }
154 178
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,9 +75,10 @@ public class SinglePointToMultiPointIntentCompiler ...@@ -75,9 +75,10 @@ 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
81 return Collections.singletonList(result); 82 return Collections.singletonList(result);
82 } 83 }
83 -} 84 +}
...\ No newline at end of file ...\ No newline at end of file
......