Committed by
Gerrit Code Review
Fix [ONOS-4857] and impement [ONOS-5143]
Change-Id: I7159ff9deaacaf10070e1535f4a80f2f846a5784
Showing
3 changed files
with
486 additions
and
294 deletions
core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionCompiler.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2016-present Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package org.onosproject.net.intent.impl.compiler; | ||
18 | + | ||
19 | +import com.google.common.collect.SetMultimap; | ||
20 | +import org.onlab.packet.Ip4Address; | ||
21 | +import org.onlab.packet.IpPrefix; | ||
22 | +import org.onosproject.net.ConnectPoint; | ||
23 | +import org.onosproject.net.DeviceId; | ||
24 | +import org.onosproject.net.Link; | ||
25 | +import org.onosproject.net.PortNumber; | ||
26 | +import org.onosproject.net.flow.DefaultTrafficSelector; | ||
27 | +import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
28 | +import org.onosproject.net.flow.TrafficSelector; | ||
29 | +import org.onosproject.net.flow.TrafficTreatment; | ||
30 | +import org.onosproject.net.flow.instructions.L0ModificationInstruction; | ||
31 | +import org.onosproject.net.flow.instructions.L1ModificationInstruction; | ||
32 | +import org.onosproject.net.flow.instructions.L2ModificationInstruction; | ||
33 | +import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction; | ||
34 | +import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsBosInstruction; | ||
35 | +import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsLabelInstruction; | ||
36 | +import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModTunnelIdInstruction; | ||
37 | +import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction; | ||
38 | +import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction; | ||
39 | +import org.onosproject.net.flow.instructions.L3ModificationInstruction; | ||
40 | +import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpEthInstruction; | ||
41 | +import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpIPInstruction; | ||
42 | +import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpOpInstruction; | ||
43 | +import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction; | ||
44 | +import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction; | ||
45 | +import org.onosproject.net.flow.instructions.L4ModificationInstruction; | ||
46 | +import org.onosproject.net.flow.instructions.L4ModificationInstruction.ModTransportPortInstruction; | ||
47 | +import org.onosproject.net.intent.IntentCompilationException; | ||
48 | +import org.onosproject.net.intent.LinkCollectionIntent; | ||
49 | + | ||
50 | +import java.util.List; | ||
51 | +import java.util.Set; | ||
52 | +import java.util.stream.Collectors; | ||
53 | + | ||
54 | +/** | ||
55 | + * Shared APIs and implementations for Link Collection compilers. | ||
56 | + */ | ||
57 | +public class LinkCollectionCompiler<T> { | ||
58 | + | ||
59 | + /** | ||
60 | + * Helper class to encapsulate treatment and selector. | ||
61 | + */ | ||
62 | + protected class ForwardingInstructions { | ||
63 | + | ||
64 | + private TrafficTreatment trafficTreatment; | ||
65 | + | ||
66 | + private TrafficSelector trafficSelector; | ||
67 | + | ||
68 | + public ForwardingInstructions(TrafficTreatment treatment, TrafficSelector selector) { | ||
69 | + | ||
70 | + this.trafficTreatment = treatment; | ||
71 | + this.trafficSelector = selector; | ||
72 | + | ||
73 | + } | ||
74 | + | ||
75 | + public TrafficTreatment treatment() { | ||
76 | + return this.trafficTreatment; | ||
77 | + } | ||
78 | + | ||
79 | + public TrafficSelector selector() { | ||
80 | + return this.trafficSelector; | ||
81 | + } | ||
82 | + | ||
83 | + } | ||
84 | + | ||
85 | + /** | ||
86 | + * Helper method to compute input and ouput ports. | ||
87 | + * | ||
88 | + * @param intent the related intents | ||
89 | + * @param inputPorts the input ports to compute | ||
90 | + * @param outputPorts the output ports to compute | ||
91 | + */ | ||
92 | + protected void computePorts(LinkCollectionIntent intent, | ||
93 | + SetMultimap<DeviceId, PortNumber> inputPorts, | ||
94 | + SetMultimap<DeviceId, PortNumber> outputPorts) { | ||
95 | + | ||
96 | + for (Link link : intent.links()) { | ||
97 | + inputPorts.put(link.dst().deviceId(), link.dst().port()); | ||
98 | + outputPorts.put(link.src().deviceId(), link.src().port()); | ||
99 | + } | ||
100 | + | ||
101 | + for (ConnectPoint ingressPoint : intent.ingressPoints()) { | ||
102 | + inputPorts.put(ingressPoint.deviceId(), ingressPoint.port()); | ||
103 | + } | ||
104 | + | ||
105 | + for (ConnectPoint egressPoint : intent.egressPoints()) { | ||
106 | + outputPorts.put(egressPoint.deviceId(), egressPoint.port()); | ||
107 | + } | ||
108 | + | ||
109 | + } | ||
110 | + | ||
111 | + /** | ||
112 | + * Helper method to compute ingress and egress ports. | ||
113 | + * | ||
114 | + * @param intent the related intents | ||
115 | + * @param ingressPorts the ingress ports to compute | ||
116 | + * @param egressPorts the egress ports to compute | ||
117 | + */ | ||
118 | + protected void computePorts(LinkCollectionIntent intent, | ||
119 | + DeviceId deviceId, | ||
120 | + Set<PortNumber> ingressPorts, | ||
121 | + Set<PortNumber> egressPorts) { | ||
122 | + | ||
123 | + if (!intent.applyTreatmentOnEgress()) { | ||
124 | + ingressPorts.addAll(intent.ingressPoints().stream() | ||
125 | + .filter(point -> point.deviceId().equals(deviceId)) | ||
126 | + .map(ConnectPoint::port) | ||
127 | + .collect(Collectors.toSet())); | ||
128 | + } else { | ||
129 | + egressPorts.addAll(intent.egressPoints().stream() | ||
130 | + .filter(point -> point.deviceId().equals(deviceId)) | ||
131 | + .map(ConnectPoint::port) | ||
132 | + .collect(Collectors.toSet())); | ||
133 | + } | ||
134 | + | ||
135 | + } | ||
136 | + | ||
137 | + /** | ||
138 | + * Creates the flows representations. | ||
139 | + * | ||
140 | + * @param intent the intent to compile | ||
141 | + * @param deviceId the affected device | ||
142 | + * @param inPorts the input ports | ||
143 | + * @param outPorts the output ports | ||
144 | + * @return the list of flows representations | ||
145 | + */ | ||
146 | + protected List<T> createRules(LinkCollectionIntent intent, DeviceId deviceId, | ||
147 | + Set<PortNumber> inPorts, Set<PortNumber> outPorts) { | ||
148 | + return null; | ||
149 | + } | ||
150 | + | ||
151 | + | ||
152 | + /** | ||
153 | + * Computes treatment and selector which will be used | ||
154 | + * in the flow representation (Rule, Objective). | ||
155 | + * | ||
156 | + * @param intent the intent to compile | ||
157 | + * @param inPort the input port | ||
158 | + * @param outPorts the output ports | ||
159 | + * @param ingressPorts the ingress ports | ||
160 | + * @param egressPorts the egress ports | ||
161 | + * @return the forwarding instruction object which encapsulates treatment and selector | ||
162 | + */ | ||
163 | + protected ForwardingInstructions createForwardingInstructions(LinkCollectionIntent intent, PortNumber inPort, | ||
164 | + Set<PortNumber> outPorts, | ||
165 | + Set<PortNumber> ingressPorts, | ||
166 | + Set<PortNumber> egressPorts) { | ||
167 | + | ||
168 | + TrafficTreatment.Builder defaultTreatmentBuilder = DefaultTrafficTreatment.builder(); | ||
169 | + outPorts.forEach(defaultTreatmentBuilder::setOutput); | ||
170 | + TrafficTreatment outputOnlyTreatment = defaultTreatmentBuilder.build(); | ||
171 | + TrafficSelector.Builder selectorBuilder; | ||
172 | + TrafficTreatment treatment; | ||
173 | + TrafficTreatment intentTreatment; | ||
174 | + | ||
175 | + if (!intent.applyTreatmentOnEgress()) { | ||
176 | + TrafficTreatment.Builder ingressTreatmentBuilder = DefaultTrafficTreatment.builder(intent.treatment()); | ||
177 | + outPorts.forEach(ingressTreatmentBuilder::setOutput); | ||
178 | + intentTreatment = ingressTreatmentBuilder.build(); | ||
179 | + | ||
180 | + if (ingressPorts.contains(inPort)) { | ||
181 | + selectorBuilder = DefaultTrafficSelector.builder(intent.selector()); | ||
182 | + treatment = intentTreatment; | ||
183 | + } else { | ||
184 | + selectorBuilder = this.createSelectorFromFwdInstructions( | ||
185 | + new ForwardingInstructions(intentTreatment, intent.selector()) | ||
186 | + ); | ||
187 | + treatment = outputOnlyTreatment; | ||
188 | + } | ||
189 | + } else { | ||
190 | + if (outPorts.stream().allMatch(egressPorts::contains)) { | ||
191 | + TrafficTreatment.Builder egressTreatmentBuilder = | ||
192 | + DefaultTrafficTreatment.builder(intent.treatment()); | ||
193 | + outPorts.forEach(egressTreatmentBuilder::setOutput); | ||
194 | + | ||
195 | + selectorBuilder = DefaultTrafficSelector.builder(intent.selector()); | ||
196 | + treatment = egressTreatmentBuilder.build(); | ||
197 | + } else { | ||
198 | + selectorBuilder = DefaultTrafficSelector.builder(intent.selector()); | ||
199 | + treatment = outputOnlyTreatment; | ||
200 | + } | ||
201 | + } | ||
202 | + | ||
203 | + TrafficSelector selector = selectorBuilder.matchInPort(inPort).build(); | ||
204 | + | ||
205 | + return new ForwardingInstructions(treatment, selector); | ||
206 | + | ||
207 | + } | ||
208 | + | ||
209 | + /** | ||
210 | + * Update the selector builder using a L0 instruction. | ||
211 | + * | ||
212 | + * @param builder the builder to update | ||
213 | + * @param l0instruction the l0 instruction to use | ||
214 | + */ | ||
215 | + private void updateBuilder(TrafficSelector.Builder builder, L0ModificationInstruction l0instruction) { | ||
216 | + throw new IntentCompilationException("L0 not supported"); | ||
217 | + } | ||
218 | + | ||
219 | + /** | ||
220 | + * Update the selector builder using a L1 instruction. | ||
221 | + * | ||
222 | + * @param builder the builder to update | ||
223 | + * @param l1instruction the l1 instruction to use | ||
224 | + */ | ||
225 | + private void updateBuilder(TrafficSelector.Builder builder, L1ModificationInstruction l1instruction) { | ||
226 | + throw new IntentCompilationException("L1 not supported"); | ||
227 | + } | ||
228 | + | ||
229 | + /** | ||
230 | + * Update the selector builder using a L2 instruction. | ||
231 | + * | ||
232 | + * @param builder the builder to update | ||
233 | + * @param l2instruction the l2 instruction to use | ||
234 | + */ | ||
235 | + private void updateBuilder(TrafficSelector.Builder builder, L2ModificationInstruction l2instruction) { | ||
236 | + switch (l2instruction.subtype()) { | ||
237 | + case ETH_SRC: | ||
238 | + case ETH_DST: | ||
239 | + ModEtherInstruction ethInstr = (ModEtherInstruction) l2instruction; | ||
240 | + switch (ethInstr.subtype()) { | ||
241 | + case ETH_SRC: | ||
242 | + builder.matchEthSrc(ethInstr.mac()); | ||
243 | + break; | ||
244 | + case ETH_DST: | ||
245 | + builder.matchEthDst(ethInstr.mac()); | ||
246 | + break; | ||
247 | + default: | ||
248 | + throw new IntentCompilationException("Bad eth subtype"); | ||
249 | + } | ||
250 | + break; | ||
251 | + case VLAN_ID: | ||
252 | + ModVlanIdInstruction vlanIdInstr = (ModVlanIdInstruction) l2instruction; | ||
253 | + builder.matchVlanId(vlanIdInstr.vlanId()); | ||
254 | + break; | ||
255 | + case VLAN_PUSH: | ||
256 | + //FIXME | ||
257 | + break; | ||
258 | + case VLAN_POP: | ||
259 | + //TODO how do we handle dropped label? remove the selector? | ||
260 | + throw new IntentCompilationException("Can't handle pop label"); | ||
261 | + case VLAN_PCP: | ||
262 | + ModVlanPcpInstruction vlanPcpInstruction = (ModVlanPcpInstruction) l2instruction; | ||
263 | + builder.matchVlanPcp(vlanPcpInstruction.vlanPcp()); | ||
264 | + break; | ||
265 | + case MPLS_LABEL: | ||
266 | + case MPLS_PUSH: | ||
267 | + //FIXME | ||
268 | + ModMplsLabelInstruction mplsInstr = (ModMplsLabelInstruction) l2instruction; | ||
269 | + builder.matchMplsLabel(mplsInstr.label()); | ||
270 | + break; | ||
271 | + case MPLS_POP: | ||
272 | + //TODO how do we handle dropped label? remove the selector? | ||
273 | + throw new IntentCompilationException("Can't handle pop label"); | ||
274 | + case DEC_MPLS_TTL: | ||
275 | + // no-op | ||
276 | + break; | ||
277 | + case MPLS_BOS: | ||
278 | + ModMplsBosInstruction mplsBosInstr = (ModMplsBosInstruction) l2instruction; | ||
279 | + builder.matchMplsBos(mplsBosInstr.mplsBos()); | ||
280 | + break; | ||
281 | + case TUNNEL_ID: | ||
282 | + ModTunnelIdInstruction tunInstr = (ModTunnelIdInstruction) l2instruction; | ||
283 | + builder.matchTunnelId(tunInstr.tunnelId()); | ||
284 | + break; | ||
285 | + default: | ||
286 | + throw new IntentCompilationException("Unknown L2 Modification instruction"); | ||
287 | + } | ||
288 | + | ||
289 | + } | ||
290 | + | ||
291 | + /** | ||
292 | + * Update the selector builder using a L3 instruction. | ||
293 | + * | ||
294 | + * @param builder the builder to update | ||
295 | + * @param l3instruction the l3 instruction to use | ||
296 | + */ | ||
297 | + private void updateBuilder(TrafficSelector.Builder builder, L3ModificationInstruction l3instruction) { | ||
298 | + // TODO check ethernet proto | ||
299 | + switch (l3instruction.subtype()) { | ||
300 | + case IPV4_SRC: | ||
301 | + case IPV4_DST: | ||
302 | + case IPV6_SRC: | ||
303 | + case IPV6_DST: | ||
304 | + ModIPInstruction ipInstr = (ModIPInstruction) l3instruction; | ||
305 | + // TODO check if ip falls in original prefix | ||
306 | + IpPrefix prefix = ipInstr.ip().toIpPrefix(); | ||
307 | + switch (ipInstr.subtype()) { | ||
308 | + case IPV4_SRC: | ||
309 | + builder.matchIPSrc(prefix); | ||
310 | + break; | ||
311 | + case IPV4_DST: | ||
312 | + builder.matchIPSrc(prefix); | ||
313 | + break; | ||
314 | + case IPV6_SRC: | ||
315 | + builder.matchIPv6Src(prefix); | ||
316 | + break; | ||
317 | + case IPV6_DST: | ||
318 | + builder.matchIPv6Dst(prefix); | ||
319 | + break; | ||
320 | + default: | ||
321 | + throw new IntentCompilationException("Bad type for IP instruction"); | ||
322 | + } | ||
323 | + break; | ||
324 | + case IPV6_FLABEL: | ||
325 | + ModIPv6FlowLabelInstruction ipFlowInstr = (ModIPv6FlowLabelInstruction) l3instruction; | ||
326 | + builder.matchIPv6FlowLabel(ipFlowInstr.flowLabel()); | ||
327 | + break; | ||
328 | + case DEC_TTL: | ||
329 | + // no-op | ||
330 | + break; | ||
331 | + case TTL_OUT: | ||
332 | + // no-op | ||
333 | + break; | ||
334 | + case TTL_IN: | ||
335 | + // no-op | ||
336 | + break; | ||
337 | + case ARP_SPA: | ||
338 | + ModArpIPInstruction arpIpInstr = (ModArpIPInstruction) l3instruction; | ||
339 | + if (arpIpInstr.ip().isIp4()) { | ||
340 | + builder.matchArpSpa((Ip4Address) arpIpInstr.ip()); | ||
341 | + } else { | ||
342 | + throw new IntentCompilationException("IPv6 not supported for ARP"); | ||
343 | + } | ||
344 | + break; | ||
345 | + case ARP_SHA: | ||
346 | + ModArpEthInstruction arpEthInstr = (ModArpEthInstruction) l3instruction; | ||
347 | + builder.matchArpSha(arpEthInstr.mac()); | ||
348 | + break; | ||
349 | + case ARP_OP: | ||
350 | + ModArpOpInstruction arpOpInstr = (ModArpOpInstruction) l3instruction; | ||
351 | + //FIXME is the long to int cast safe? | ||
352 | + builder.matchArpOp((int) arpOpInstr.op()); | ||
353 | + break; | ||
354 | + default: | ||
355 | + throw new IntentCompilationException("Unknown L3 Modification instruction"); | ||
356 | + } | ||
357 | + } | ||
358 | + | ||
359 | + /** | ||
360 | + * Update the selector builder using a L4 instruction. | ||
361 | + * | ||
362 | + * @param builder the builder to update | ||
363 | + * @param l4instruction the l4 instruction to use | ||
364 | + */ | ||
365 | + private void updateBuilder(TrafficSelector.Builder builder, L4ModificationInstruction l4instruction) { | ||
366 | + if (l4instruction instanceof ModTransportPortInstruction) { | ||
367 | + // TODO check IP proto | ||
368 | + ModTransportPortInstruction l4mod = (ModTransportPortInstruction) l4instruction; | ||
369 | + switch (l4mod.subtype()) { | ||
370 | + case TCP_SRC: | ||
371 | + builder.matchTcpSrc(l4mod.port()); | ||
372 | + break; | ||
373 | + case TCP_DST: | ||
374 | + builder.matchTcpDst(l4mod.port()); | ||
375 | + break; | ||
376 | + case UDP_SRC: | ||
377 | + builder.matchUdpSrc(l4mod.port()); | ||
378 | + break; | ||
379 | + case UDP_DST: | ||
380 | + builder.matchUdpDst(l4mod.port()); | ||
381 | + break; | ||
382 | + default: | ||
383 | + throw new IntentCompilationException("Unknown L4 Modification instruction"); | ||
384 | + } | ||
385 | + } else { | ||
386 | + throw new IntentCompilationException("Unknown L4 Modification instruction"); | ||
387 | + } | ||
388 | + } | ||
389 | + | ||
390 | + /** | ||
391 | + * Computes the new traffic selector using the | ||
392 | + * forwarding instructions. | ||
393 | + * | ||
394 | + * @param fwInstructions it encapsulates the instructions to compute the new selector | ||
395 | + * @return the traffic selector builder | ||
396 | + */ | ||
397 | + private TrafficSelector.Builder createSelectorFromFwdInstructions(ForwardingInstructions fwInstructions) { | ||
398 | + TrafficSelector.Builder defaultSelectorBuilder = DefaultTrafficSelector.builder(fwInstructions.selector()); | ||
399 | + fwInstructions.treatment().allInstructions().forEach(instruction -> { | ||
400 | + switch (instruction.type()) { | ||
401 | + case L0MODIFICATION: | ||
402 | + updateBuilder(defaultSelectorBuilder, (L0ModificationInstruction) instruction); | ||
403 | + break; | ||
404 | + case L1MODIFICATION: | ||
405 | + updateBuilder(defaultSelectorBuilder, (L1ModificationInstruction) instruction); | ||
406 | + break; | ||
407 | + case L2MODIFICATION: | ||
408 | + updateBuilder(defaultSelectorBuilder, (L2ModificationInstruction) instruction); | ||
409 | + break; | ||
410 | + case L3MODIFICATION: | ||
411 | + updateBuilder(defaultSelectorBuilder, (L3ModificationInstruction) instruction); | ||
412 | + break; | ||
413 | + case L4MODIFICATION: | ||
414 | + updateBuilder(defaultSelectorBuilder, (L4ModificationInstruction) instruction); | ||
415 | + break; | ||
416 | + case NOACTION: | ||
417 | + case OUTPUT: | ||
418 | + case GROUP: | ||
419 | + case QUEUE: | ||
420 | + case TABLE: | ||
421 | + case METER: | ||
422 | + case METADATA: | ||
423 | + case EXTENSION: // TODO is extension no-op or unsupported? | ||
424 | + // Nothing to do | ||
425 | + break; | ||
426 | + default: | ||
427 | + throw new IntentCompilationException("Unknown instruction type"); | ||
428 | + } | ||
429 | + }); | ||
430 | + return defaultSelectorBuilder; | ||
431 | + } | ||
432 | + | ||
433 | +} |
... | @@ -16,43 +16,22 @@ | ... | @@ -16,43 +16,22 @@ |
16 | package org.onosproject.net.intent.impl.compiler; | 16 | package org.onosproject.net.intent.impl.compiler; |
17 | 17 | ||
18 | import com.google.common.collect.HashMultimap; | 18 | import com.google.common.collect.HashMultimap; |
19 | +import com.google.common.collect.ImmutableSet; | ||
19 | import com.google.common.collect.SetMultimap; | 20 | import com.google.common.collect.SetMultimap; |
21 | +import com.google.common.collect.Sets; | ||
20 | import org.apache.felix.scr.annotations.Activate; | 22 | import org.apache.felix.scr.annotations.Activate; |
21 | import org.apache.felix.scr.annotations.Component; | 23 | import org.apache.felix.scr.annotations.Component; |
22 | import org.apache.felix.scr.annotations.Deactivate; | 24 | import org.apache.felix.scr.annotations.Deactivate; |
23 | import org.apache.felix.scr.annotations.Reference; | 25 | import org.apache.felix.scr.annotations.Reference; |
24 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 26 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
25 | -import org.onlab.packet.Ip4Address; | ||
26 | -import org.onlab.packet.IpPrefix; | ||
27 | import org.onosproject.core.ApplicationId; | 27 | import org.onosproject.core.ApplicationId; |
28 | import org.onosproject.core.CoreService; | 28 | import org.onosproject.core.CoreService; |
29 | -import org.onosproject.net.ConnectPoint; | ||
30 | import org.onosproject.net.DeviceId; | 29 | import org.onosproject.net.DeviceId; |
31 | -import org.onosproject.net.Link; | ||
32 | import org.onosproject.net.PortNumber; | 30 | import org.onosproject.net.PortNumber; |
33 | import org.onosproject.net.flow.DefaultFlowRule; | 31 | import org.onosproject.net.flow.DefaultFlowRule; |
34 | -import org.onosproject.net.flow.DefaultTrafficSelector; | ||
35 | -import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
36 | import org.onosproject.net.flow.FlowRule; | 32 | import org.onosproject.net.flow.FlowRule; |
37 | -import org.onosproject.net.flow.TrafficSelector; | ||
38 | -import org.onosproject.net.flow.TrafficTreatment; | ||
39 | -import org.onosproject.net.flow.instructions.L2ModificationInstruction; | ||
40 | -import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction; | ||
41 | -import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsBosInstruction; | ||
42 | -import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsLabelInstruction; | ||
43 | -import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModTunnelIdInstruction; | ||
44 | -import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction; | ||
45 | -import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction; | ||
46 | -import org.onosproject.net.flow.instructions.L3ModificationInstruction; | ||
47 | -import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpEthInstruction; | ||
48 | -import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpIPInstruction; | ||
49 | -import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpOpInstruction; | ||
50 | -import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction; | ||
51 | -import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction; | ||
52 | -import org.onosproject.net.flow.instructions.L4ModificationInstruction.ModTransportPortInstruction; | ||
53 | import org.onosproject.net.intent.FlowRuleIntent; | 33 | import org.onosproject.net.intent.FlowRuleIntent; |
54 | import org.onosproject.net.intent.Intent; | 34 | import org.onosproject.net.intent.Intent; |
55 | -import org.onosproject.net.intent.IntentCompilationException; | ||
56 | import org.onosproject.net.intent.IntentCompiler; | 35 | import org.onosproject.net.intent.IntentCompiler; |
57 | import org.onosproject.net.intent.LinkCollectionIntent; | 36 | import org.onosproject.net.intent.LinkCollectionIntent; |
58 | 37 | ||
... | @@ -60,10 +39,14 @@ import java.util.ArrayList; | ... | @@ -60,10 +39,14 @@ import java.util.ArrayList; |
60 | import java.util.Collections; | 39 | import java.util.Collections; |
61 | import java.util.List; | 40 | import java.util.List; |
62 | import java.util.Set; | 41 | import java.util.Set; |
63 | -import java.util.stream.Collectors; | ||
64 | 42 | ||
43 | +/** | ||
44 | + * Compiler to produce flow rules from link collections. | ||
45 | + */ | ||
65 | @Component(immediate = true) | 46 | @Component(immediate = true) |
66 | -public class LinkCollectionIntentCompiler implements IntentCompiler<LinkCollectionIntent> { | 47 | +public class LinkCollectionIntentCompiler |
48 | + extends LinkCollectionCompiler<FlowRule> | ||
49 | + implements IntentCompiler<LinkCollectionIntent> { | ||
67 | 50 | ||
68 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 51 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
69 | protected IntentConfigurableRegistrator registrator; | 52 | protected IntentConfigurableRegistrator registrator; |
... | @@ -86,21 +69,11 @@ public class LinkCollectionIntentCompiler implements IntentCompiler<LinkCollecti | ... | @@ -86,21 +69,11 @@ public class LinkCollectionIntentCompiler implements IntentCompiler<LinkCollecti |
86 | 69 | ||
87 | @Override | 70 | @Override |
88 | public List<Intent> compile(LinkCollectionIntent intent, List<Intent> installable) { | 71 | public List<Intent> compile(LinkCollectionIntent intent, List<Intent> installable) { |
72 | + | ||
89 | SetMultimap<DeviceId, PortNumber> inputPorts = HashMultimap.create(); | 73 | SetMultimap<DeviceId, PortNumber> inputPorts = HashMultimap.create(); |
90 | SetMultimap<DeviceId, PortNumber> outputPorts = HashMultimap.create(); | 74 | SetMultimap<DeviceId, PortNumber> outputPorts = HashMultimap.create(); |
91 | 75 | ||
92 | - for (Link link : intent.links()) { | 76 | + computePorts(intent, inputPorts, outputPorts); |
93 | - inputPorts.put(link.dst().deviceId(), link.dst().port()); | ||
94 | - outputPorts.put(link.src().deviceId(), link.src().port()); | ||
95 | - } | ||
96 | - | ||
97 | - for (ConnectPoint ingressPoint : intent.ingressPoints()) { | ||
98 | - inputPorts.put(ingressPoint.deviceId(), ingressPoint.port()); | ||
99 | - } | ||
100 | - | ||
101 | - for (ConnectPoint egressPoint : intent.egressPoints()) { | ||
102 | - outputPorts.put(egressPoint.deviceId(), egressPoint.port()); | ||
103 | - } | ||
104 | 77 | ||
105 | List<FlowRule> rules = new ArrayList<>(); | 78 | List<FlowRule> rules = new ArrayList<>(); |
106 | for (DeviceId deviceId: outputPorts.keys()) { | 79 | for (DeviceId deviceId: outputPorts.keys()) { |
... | @@ -109,235 +82,37 @@ public class LinkCollectionIntentCompiler implements IntentCompiler<LinkCollecti | ... | @@ -109,235 +82,37 @@ public class LinkCollectionIntentCompiler implements IntentCompiler<LinkCollecti |
109 | return Collections.singletonList(new FlowRuleIntent(appId, rules, intent.resources())); | 82 | return Collections.singletonList(new FlowRuleIntent(appId, rules, intent.resources())); |
110 | } | 83 | } |
111 | 84 | ||
112 | - private List<FlowRule> createRules(LinkCollectionIntent intent, DeviceId deviceId, | 85 | + @Override |
86 | + protected List<FlowRule> createRules(LinkCollectionIntent intent, DeviceId deviceId, | ||
113 | Set<PortNumber> inPorts, Set<PortNumber> outPorts) { | 87 | Set<PortNumber> inPorts, Set<PortNumber> outPorts) { |
114 | - TrafficTreatment.Builder defaultTreatmentBuilder = DefaultTrafficTreatment.builder(); | ||
115 | - outPorts.forEach(defaultTreatmentBuilder::setOutput); | ||
116 | - TrafficTreatment outputOnlyTreatment = defaultTreatmentBuilder.build(); | ||
117 | - Set<PortNumber> ingressPorts = Collections.emptySet(); | ||
118 | - Set<PortNumber> egressPorts = Collections.emptySet(); | ||
119 | - | ||
120 | - if (!intent.applyTreatmentOnEgress()) { | ||
121 | - ingressPorts = intent.ingressPoints().stream() | ||
122 | - .filter(point -> point.deviceId().equals(deviceId)) | ||
123 | - .map(ConnectPoint::port) | ||
124 | - .collect(Collectors.toSet()); | ||
125 | - } else { | ||
126 | - egressPorts = intent.egressPoints().stream() | ||
127 | - .filter(point -> point.deviceId().equals(deviceId)) | ||
128 | - .map(ConnectPoint::port) | ||
129 | - .collect(Collectors.toSet()); | ||
130 | - } | ||
131 | 88 | ||
132 | - List<FlowRule> rules = new ArrayList<>(inPorts.size()); | 89 | + Set<PortNumber> ingressPorts = Sets.newHashSet(); |
133 | - for (PortNumber inPort: inPorts) { | 90 | + Set<PortNumber> egressPorts = Sets.newHashSet(); |
134 | - TrafficSelector.Builder selectorBuilder; | ||
135 | - TrafficTreatment treatment; | ||
136 | - TrafficTreatment intentTreatment; | ||
137 | 91 | ||
138 | - if (!intent.applyTreatmentOnEgress()) { | 92 | + computePorts(intent, deviceId, ingressPorts, egressPorts); |
139 | - TrafficTreatment.Builder ingressTreatmentBuilder = DefaultTrafficTreatment.builder(intent.treatment()); | ||
140 | - outPorts.forEach(ingressTreatmentBuilder::setOutput); | ||
141 | - intentTreatment = ingressTreatmentBuilder.build(); | ||
142 | - | ||
143 | - if (ingressPorts.contains(inPort)) { | ||
144 | - selectorBuilder = DefaultTrafficSelector.builder(intent.selector()); | ||
145 | - treatment = intentTreatment; | ||
146 | - } else { | ||
147 | - selectorBuilder = applyTreatmentToSelector(intent.selector(), intentTreatment); | ||
148 | - treatment = outputOnlyTreatment; | ||
149 | - } | ||
150 | - } else { | ||
151 | - if (outPorts.stream().allMatch(egressPorts::contains)) { | ||
152 | - TrafficTreatment.Builder egressTreatmentBuilder = | ||
153 | - DefaultTrafficTreatment.builder(intent.treatment()); | ||
154 | - outPorts.forEach(egressTreatmentBuilder::setOutput); | ||
155 | - | ||
156 | - selectorBuilder = DefaultTrafficSelector.builder(intent.selector()); | ||
157 | - treatment = egressTreatmentBuilder.build(); | ||
158 | - } else { | ||
159 | - selectorBuilder = DefaultTrafficSelector.builder(intent.selector()); | ||
160 | - treatment = outputOnlyTreatment; | ||
161 | - } | ||
162 | - } | ||
163 | - TrafficSelector selector = selectorBuilder.matchInPort(inPort).build(); | ||
164 | 93 | ||
94 | + List<FlowRule> rules = new ArrayList<>(inPorts.size()); | ||
95 | + Set<PortNumber> copyIngressPorts = ImmutableSet.copyOf(ingressPorts); | ||
96 | + Set<PortNumber> copyEgressPorts = ImmutableSet.copyOf(egressPorts); | ||
97 | + | ||
98 | + inPorts.forEach(inport -> { | ||
99 | + ForwardingInstructions instructions = this.createForwardingInstructions(intent, | ||
100 | + inport, | ||
101 | + outPorts, | ||
102 | + copyIngressPorts, | ||
103 | + copyEgressPorts); | ||
165 | FlowRule rule = DefaultFlowRule.builder() | 104 | FlowRule rule = DefaultFlowRule.builder() |
166 | .forDevice(deviceId) | 105 | .forDevice(deviceId) |
167 | - .withSelector(selector) | 106 | + .withSelector(instructions.selector()) |
168 | - .withTreatment(treatment) | 107 | + .withTreatment(instructions.treatment()) |
169 | .withPriority(intent.priority()) | 108 | .withPriority(intent.priority()) |
170 | .fromApp(appId) | 109 | .fromApp(appId) |
171 | .makePermanent() | 110 | .makePermanent() |
172 | .build(); | 111 | .build(); |
173 | rules.add(rule); | 112 | rules.add(rule); |
174 | } | 113 | } |
114 | + ); | ||
175 | 115 | ||
176 | return rules; | 116 | return rules; |
177 | } | 117 | } |
178 | - | ||
179 | - private TrafficSelector.Builder applyTreatmentToSelector(TrafficSelector selector, TrafficTreatment treatment) { | ||
180 | - TrafficSelector.Builder defaultSelectorBuilder = DefaultTrafficSelector.builder(selector); | ||
181 | - treatment.allInstructions().forEach(instruction -> { | ||
182 | - switch (instruction.type()) { | ||
183 | - case L0MODIFICATION: | ||
184 | - case L1MODIFICATION: | ||
185 | - throw new IntentCompilationException("L0 and L1 mods not supported"); | ||
186 | - case L2MODIFICATION: | ||
187 | - L2ModificationInstruction l2mod = (L2ModificationInstruction) instruction; | ||
188 | - switch (l2mod.subtype()) { | ||
189 | - case ETH_SRC: | ||
190 | - case ETH_DST: | ||
191 | - ModEtherInstruction ethInstr = (ModEtherInstruction) l2mod; | ||
192 | - switch (ethInstr.subtype()) { | ||
193 | - case ETH_SRC: | ||
194 | - defaultSelectorBuilder.matchEthSrc(ethInstr.mac()); | ||
195 | - break; | ||
196 | - case ETH_DST: | ||
197 | - defaultSelectorBuilder.matchEthDst(ethInstr.mac()); | ||
198 | - break; | ||
199 | - default: | ||
200 | - throw new IntentCompilationException("Bad eth subtype"); | ||
201 | - } | ||
202 | - break; | ||
203 | - case VLAN_ID: | ||
204 | - ModVlanIdInstruction vlanIdInstr = (ModVlanIdInstruction) l2mod; | ||
205 | - defaultSelectorBuilder.matchVlanId(vlanIdInstr.vlanId()); | ||
206 | - break; | ||
207 | - case VLAN_PUSH: | ||
208 | - //FIXME | ||
209 | - break; | ||
210 | - case VLAN_POP: | ||
211 | - //TODO how do we handle dropped label? remove the selector? | ||
212 | - throw new IntentCompilationException("Can't handle pop label"); | ||
213 | - case VLAN_PCP: | ||
214 | - ModVlanPcpInstruction vlanPcpInstruction = (ModVlanPcpInstruction) l2mod; | ||
215 | - defaultSelectorBuilder.matchVlanPcp(vlanPcpInstruction.vlanPcp()); | ||
216 | - break; | ||
217 | - case MPLS_LABEL: | ||
218 | - case MPLS_PUSH: | ||
219 | - //FIXME | ||
220 | - ModMplsLabelInstruction mplsInstr = (ModMplsLabelInstruction) l2mod; | ||
221 | - defaultSelectorBuilder.matchMplsLabel(mplsInstr.label()); | ||
222 | - break; | ||
223 | - case MPLS_POP: | ||
224 | - //TODO how do we handle dropped label? remove the selector? | ||
225 | - throw new IntentCompilationException("Can't handle pop label"); | ||
226 | - case DEC_MPLS_TTL: | ||
227 | - // no-op | ||
228 | - break; | ||
229 | - case MPLS_BOS: | ||
230 | - ModMplsBosInstruction mplsBosInstr = (ModMplsBosInstruction) l2mod; | ||
231 | - defaultSelectorBuilder.matchMplsBos(mplsBosInstr.mplsBos()); | ||
232 | - break; | ||
233 | - case TUNNEL_ID: | ||
234 | - ModTunnelIdInstruction tunInstr = (ModTunnelIdInstruction) l2mod; | ||
235 | - defaultSelectorBuilder.matchTunnelId(tunInstr.tunnelId()); | ||
236 | - break; | ||
237 | - default: | ||
238 | - throw new IntentCompilationException("Unknown L2 Modification instruction"); | ||
239 | - } | ||
240 | - break; | ||
241 | - case L3MODIFICATION: | ||
242 | - L3ModificationInstruction l3mod = (L3ModificationInstruction) instruction; | ||
243 | - // TODO check ethernet proto | ||
244 | - switch (l3mod.subtype()) { | ||
245 | - case IPV4_SRC: | ||
246 | - case IPV4_DST: | ||
247 | - case IPV6_SRC: | ||
248 | - case IPV6_DST: | ||
249 | - ModIPInstruction ipInstr = (ModIPInstruction) l3mod; | ||
250 | - // TODO check if ip falls in original prefix | ||
251 | - IpPrefix prefix = ipInstr.ip().toIpPrefix(); | ||
252 | - switch (ipInstr.subtype()) { | ||
253 | - case IPV4_SRC: | ||
254 | - defaultSelectorBuilder.matchIPSrc(prefix); | ||
255 | - break; | ||
256 | - case IPV4_DST: | ||
257 | - defaultSelectorBuilder.matchIPSrc(prefix); | ||
258 | - break; | ||
259 | - case IPV6_SRC: | ||
260 | - defaultSelectorBuilder.matchIPv6Src(prefix); | ||
261 | - break; | ||
262 | - case IPV6_DST: | ||
263 | - defaultSelectorBuilder.matchIPv6Dst(prefix); | ||
264 | - break; | ||
265 | - default: | ||
266 | - throw new IntentCompilationException("Bad type for IP instruction"); | ||
267 | - } | ||
268 | - break; | ||
269 | - case IPV6_FLABEL: | ||
270 | - ModIPv6FlowLabelInstruction ipFlowInstr = (ModIPv6FlowLabelInstruction) l3mod; | ||
271 | - defaultSelectorBuilder.matchIPv6FlowLabel(ipFlowInstr.flowLabel()); | ||
272 | - break; | ||
273 | - case DEC_TTL: | ||
274 | - // no-op | ||
275 | - break; | ||
276 | - case TTL_OUT: | ||
277 | - // no-op | ||
278 | - break; | ||
279 | - case TTL_IN: | ||
280 | - // no-op | ||
281 | - break; | ||
282 | - case ARP_SPA: | ||
283 | - ModArpIPInstruction arpIpInstr = (ModArpIPInstruction) l3mod; | ||
284 | - if (arpIpInstr.ip().isIp4()) { | ||
285 | - defaultSelectorBuilder.matchArpSpa((Ip4Address) arpIpInstr.ip()); | ||
286 | - } else { | ||
287 | - throw new IntentCompilationException("IPv6 not supported for ARP"); | ||
288 | - } | ||
289 | - break; | ||
290 | - case ARP_SHA: | ||
291 | - ModArpEthInstruction arpEthInstr = (ModArpEthInstruction) l3mod; | ||
292 | - defaultSelectorBuilder.matchArpSha(arpEthInstr.mac()); | ||
293 | - break; | ||
294 | - case ARP_OP: | ||
295 | - ModArpOpInstruction arpOpInstr = (ModArpOpInstruction) l3mod; | ||
296 | - //FIXME is the long to int cast safe? | ||
297 | - defaultSelectorBuilder.matchArpOp((int) arpOpInstr.op()); | ||
298 | - break; | ||
299 | - default: | ||
300 | - throw new IntentCompilationException("Unknown L3 Modification instruction"); | ||
301 | - } | ||
302 | - break; | ||
303 | - case L4MODIFICATION: | ||
304 | - if (instruction instanceof ModTransportPortInstruction) { | ||
305 | - // TODO check IP proto | ||
306 | - ModTransportPortInstruction l4mod = (ModTransportPortInstruction) instruction; | ||
307 | - switch (l4mod.subtype()) { | ||
308 | - case TCP_SRC: | ||
309 | - defaultSelectorBuilder.matchTcpSrc(l4mod.port()); | ||
310 | - break; | ||
311 | - case TCP_DST: | ||
312 | - defaultSelectorBuilder.matchTcpDst(l4mod.port()); | ||
313 | - break; | ||
314 | - case UDP_SRC: | ||
315 | - defaultSelectorBuilder.matchUdpSrc(l4mod.port()); | ||
316 | - break; | ||
317 | - case UDP_DST: | ||
318 | - defaultSelectorBuilder.matchUdpDst(l4mod.port()); | ||
319 | - break; | ||
320 | - default: | ||
321 | - throw new IntentCompilationException("Unknown L4 Modification instruction"); | ||
322 | - } | ||
323 | - } else { | ||
324 | - throw new IntentCompilationException("Unknown L4 Modification instruction"); | ||
325 | - } | ||
326 | - break; | ||
327 | - case NOACTION: | ||
328 | - case OUTPUT: | ||
329 | - case GROUP: | ||
330 | - case QUEUE: | ||
331 | - case TABLE: | ||
332 | - case METER: | ||
333 | - case METADATA: | ||
334 | - case EXTENSION: // TODO is extension no-op or unsupported? | ||
335 | - // Nothing to do | ||
336 | - break; | ||
337 | - default: | ||
338 | - throw new IntentCompilationException("Unknown instruction type"); | ||
339 | - } | ||
340 | - }); | ||
341 | - return defaultSelectorBuilder; | ||
342 | - } | ||
343 | } | 118 | } | ... | ... |
... | @@ -16,7 +16,9 @@ | ... | @@ -16,7 +16,9 @@ |
16 | package org.onosproject.net.intent.impl.compiler; | 16 | package org.onosproject.net.intent.impl.compiler; |
17 | 17 | ||
18 | import com.google.common.collect.HashMultimap; | 18 | import com.google.common.collect.HashMultimap; |
19 | +import com.google.common.collect.ImmutableSet; | ||
19 | import com.google.common.collect.SetMultimap; | 20 | import com.google.common.collect.SetMultimap; |
21 | +import com.google.common.collect.Sets; | ||
20 | import org.apache.felix.scr.annotations.Activate; | 22 | import org.apache.felix.scr.annotations.Activate; |
21 | import org.apache.felix.scr.annotations.Component; | 23 | import org.apache.felix.scr.annotations.Component; |
22 | import org.apache.felix.scr.annotations.Deactivate; | 24 | import org.apache.felix.scr.annotations.Deactivate; |
... | @@ -24,14 +26,8 @@ import org.apache.felix.scr.annotations.Reference; | ... | @@ -24,14 +26,8 @@ import org.apache.felix.scr.annotations.Reference; |
24 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 26 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
25 | import org.onosproject.core.ApplicationId; | 27 | import org.onosproject.core.ApplicationId; |
26 | import org.onosproject.core.CoreService; | 28 | import org.onosproject.core.CoreService; |
27 | -import org.onosproject.net.ConnectPoint; | ||
28 | import org.onosproject.net.DeviceId; | 29 | import org.onosproject.net.DeviceId; |
29 | -import org.onosproject.net.Link; | ||
30 | import org.onosproject.net.PortNumber; | 30 | import org.onosproject.net.PortNumber; |
31 | -import org.onosproject.net.flow.DefaultTrafficSelector; | ||
32 | -import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
33 | -import org.onosproject.net.flow.TrafficSelector; | ||
34 | -import org.onosproject.net.flow.TrafficTreatment; | ||
35 | import org.onosproject.net.flowobjective.DefaultForwardingObjective; | 31 | import org.onosproject.net.flowobjective.DefaultForwardingObjective; |
36 | import org.onosproject.net.flowobjective.DefaultNextObjective; | 32 | import org.onosproject.net.flowobjective.DefaultNextObjective; |
37 | import org.onosproject.net.flowobjective.FlowObjectiveService; | 33 | import org.onosproject.net.flowobjective.FlowObjectiveService; |
... | @@ -47,13 +43,14 @@ import java.util.ArrayList; | ... | @@ -47,13 +43,14 @@ import java.util.ArrayList; |
47 | import java.util.Collections; | 43 | import java.util.Collections; |
48 | import java.util.List; | 44 | import java.util.List; |
49 | import java.util.Set; | 45 | import java.util.Set; |
50 | -import java.util.stream.Collectors; | ||
51 | 46 | ||
52 | /** | 47 | /** |
53 | * Compiler to produce flow objectives from link collections. | 48 | * Compiler to produce flow objectives from link collections. |
54 | */ | 49 | */ |
55 | @Component(immediate = true) | 50 | @Component(immediate = true) |
56 | -public class LinkCollectionIntentFlowObjectivesCompiler implements IntentCompiler<LinkCollectionIntent> { | 51 | +public class LinkCollectionIntentFlowObjectiveCompiler |
52 | + extends LinkCollectionCompiler<Objective> | ||
53 | + implements IntentCompiler<LinkCollectionIntent> { | ||
57 | 54 | ||
58 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 55 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
59 | protected IntentConfigurableRegistrator registrator; | 56 | protected IntentConfigurableRegistrator registrator; |
... | @@ -79,21 +76,11 @@ public class LinkCollectionIntentFlowObjectivesCompiler implements IntentCompile | ... | @@ -79,21 +76,11 @@ public class LinkCollectionIntentFlowObjectivesCompiler implements IntentCompile |
79 | 76 | ||
80 | @Override | 77 | @Override |
81 | public List<Intent> compile(LinkCollectionIntent intent, List<Intent> installable) { | 78 | public List<Intent> compile(LinkCollectionIntent intent, List<Intent> installable) { |
79 | + | ||
82 | SetMultimap<DeviceId, PortNumber> inputPorts = HashMultimap.create(); | 80 | SetMultimap<DeviceId, PortNumber> inputPorts = HashMultimap.create(); |
83 | SetMultimap<DeviceId, PortNumber> outputPorts = HashMultimap.create(); | 81 | SetMultimap<DeviceId, PortNumber> outputPorts = HashMultimap.create(); |
84 | 82 | ||
85 | - for (Link link : intent.links()) { | 83 | + computePorts(intent, inputPorts, outputPorts); |
86 | - inputPorts.put(link.dst().deviceId(), link.dst().port()); | ||
87 | - outputPorts.put(link.src().deviceId(), link.src().port()); | ||
88 | - } | ||
89 | - | ||
90 | - for (ConnectPoint ingressPoint : intent.ingressPoints()) { | ||
91 | - inputPorts.put(ingressPoint.deviceId(), ingressPoint.port()); | ||
92 | - } | ||
93 | - | ||
94 | - for (ConnectPoint egressPoint : intent.egressPoints()) { | ||
95 | - outputPorts.put(egressPoint.deviceId(), egressPoint.port()); | ||
96 | - } | ||
97 | 84 | ||
98 | List<Objective> objectives = new ArrayList<>(); | 85 | List<Objective> objectives = new ArrayList<>(); |
99 | List<DeviceId> devices = new ArrayList<>(); | 86 | List<DeviceId> devices = new ArrayList<>(); |
... | @@ -112,41 +99,36 @@ public class LinkCollectionIntentFlowObjectivesCompiler implements IntentCompile | ... | @@ -112,41 +99,36 @@ public class LinkCollectionIntentFlowObjectivesCompiler implements IntentCompile |
112 | new FlowObjectiveIntent(appId, devices, objectives, intent.resources())); | 99 | new FlowObjectiveIntent(appId, devices, objectives, intent.resources())); |
113 | } | 100 | } |
114 | 101 | ||
115 | - private List<Objective> createRules(LinkCollectionIntent intent, DeviceId deviceId, | 102 | + @Override |
103 | + protected List<Objective> createRules(LinkCollectionIntent intent, DeviceId deviceId, | ||
116 | Set<PortNumber> inPorts, Set<PortNumber> outPorts) { | 104 | Set<PortNumber> inPorts, Set<PortNumber> outPorts) { |
117 | - Set<PortNumber> ingressPorts = intent.ingressPoints().stream() | ||
118 | - .filter(point -> point.deviceId().equals(deviceId)) | ||
119 | - .map(ConnectPoint::port) | ||
120 | - .collect(Collectors.toSet()); | ||
121 | 105 | ||
122 | - TrafficTreatment.Builder defaultTreatmentBuilder = DefaultTrafficTreatment.builder(); | 106 | + Set<PortNumber> ingressPorts = Sets.newHashSet(); |
123 | - outPorts.forEach(defaultTreatmentBuilder::setOutput); | 107 | + Set<PortNumber> egressPorts = Sets.newHashSet(); |
124 | - TrafficTreatment defaultTreatment = defaultTreatmentBuilder.build(); | ||
125 | 108 | ||
126 | - TrafficTreatment.Builder ingressTreatmentBuilder = DefaultTrafficTreatment.builder(intent.treatment()); | 109 | + computePorts(intent, deviceId, ingressPorts, egressPorts); |
127 | - outPorts.forEach(ingressTreatmentBuilder::setOutput); | ||
128 | - TrafficTreatment ingressTreatment = ingressTreatmentBuilder.build(); | ||
129 | 110 | ||
130 | List<Objective> objectives = new ArrayList<>(inPorts.size()); | 111 | List<Objective> objectives = new ArrayList<>(inPorts.size()); |
131 | - for (PortNumber inPort: inPorts) { | 112 | + Set<PortNumber> copyIngressPorts = ImmutableSet.copyOf(ingressPorts); |
132 | - TrafficSelector selector = DefaultTrafficSelector.builder(intent.selector()).matchInPort(inPort).build(); | 113 | + Set<PortNumber> copyEgressPorts = ImmutableSet.copyOf(egressPorts); |
133 | - TrafficTreatment treatment; | 114 | + |
134 | - if (ingressPorts.contains(inPort)) { | 115 | + inPorts.forEach(inport -> { |
135 | - treatment = ingressTreatment; | 116 | + ForwardingInstructions instructions = this.createForwardingInstructions(intent, |
136 | - } else { | 117 | + inport, |
137 | - treatment = defaultTreatment; | 118 | + outPorts, |
138 | - } | 119 | + copyIngressPorts, |
120 | + copyEgressPorts); | ||
139 | 121 | ||
140 | NextObjective nextObjective = DefaultNextObjective.builder() | 122 | NextObjective nextObjective = DefaultNextObjective.builder() |
141 | .withId(flowObjectiveService.allocateNextId()) | 123 | .withId(flowObjectiveService.allocateNextId()) |
142 | - .addTreatment(treatment) | 124 | + .addTreatment(instructions.treatment()) |
143 | .withType(NextObjective.Type.SIMPLE) | 125 | .withType(NextObjective.Type.SIMPLE) |
144 | .fromApp(appId) | 126 | .fromApp(appId) |
145 | .makePermanent().add(); | 127 | .makePermanent().add(); |
146 | objectives.add(nextObjective); | 128 | objectives.add(nextObjective); |
147 | 129 | ||
148 | objectives.add(DefaultForwardingObjective.builder() | 130 | objectives.add(DefaultForwardingObjective.builder() |
149 | - .withSelector(selector) | 131 | + .withSelector(instructions.selector()) |
150 | .nextStep(nextObjective.id()) | 132 | .nextStep(nextObjective.id()) |
151 | .withPriority(intent.priority()) | 133 | .withPriority(intent.priority()) |
152 | .fromApp(appId) | 134 | .fromApp(appId) |
... | @@ -154,7 +136,9 @@ public class LinkCollectionIntentFlowObjectivesCompiler implements IntentCompile | ... | @@ -154,7 +136,9 @@ public class LinkCollectionIntentFlowObjectivesCompiler implements IntentCompile |
154 | .withFlag(ForwardingObjective.Flag.SPECIFIC) | 136 | .withFlag(ForwardingObjective.Flag.SPECIFIC) |
155 | .add()); | 137 | .add()); |
156 | } | 138 | } |
139 | + ); | ||
157 | 140 | ||
158 | return objectives; | 141 | return objectives; |
159 | } | 142 | } |
143 | + | ||
160 | } | 144 | } | ... | ... |
-
Please register or login to post a comment