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
Showing
3 changed files
with
198 additions
and
23 deletions
... | @@ -93,14 +93,14 @@ public abstract class AbstractCorsaPipeline extends AbstractHandlerBehaviour imp | ... | @@ -93,14 +93,14 @@ public abstract class AbstractCorsaPipeline extends AbstractHandlerBehaviour imp |
93 | private ServiceDirectory serviceDirectory; | 93 | private ServiceDirectory serviceDirectory; |
94 | protected FlowRuleService flowRuleService; | 94 | protected FlowRuleService flowRuleService; |
95 | private CoreService coreService; | 95 | private CoreService coreService; |
96 | - private GroupService groupService; | 96 | + protected GroupService groupService; |
97 | protected MeterService meterService; | 97 | protected MeterService meterService; |
98 | - private FlowObjectiveStore flowObjectiveStore; | 98 | + protected FlowObjectiveStore flowObjectiveStore; |
99 | protected DeviceId deviceId; | 99 | protected DeviceId deviceId; |
100 | protected ApplicationId appId; | 100 | protected ApplicationId appId; |
101 | protected DeviceService deviceService; | 101 | protected DeviceService deviceService; |
102 | 102 | ||
103 | - private KryoNamespace appKryo = new KryoNamespace.Builder() | 103 | + protected KryoNamespace appKryo = new KryoNamespace.Builder() |
104 | .register(GroupKey.class) | 104 | .register(GroupKey.class) |
105 | .register(DefaultGroupKey.class) | 105 | .register(DefaultGroupKey.class) |
106 | .register(CorsaGroup.class) | 106 | .register(CorsaGroup.class) |
... | @@ -108,6 +108,8 @@ public abstract class AbstractCorsaPipeline extends AbstractHandlerBehaviour imp | ... | @@ -108,6 +108,8 @@ public abstract class AbstractCorsaPipeline extends AbstractHandlerBehaviour imp |
108 | .build("AbstractCorsaPipeline"); | 108 | .build("AbstractCorsaPipeline"); |
109 | 109 | ||
110 | private Cache<GroupKey, NextObjective> pendingGroups; | 110 | private Cache<GroupKey, NextObjective> pendingGroups; |
111 | + protected Cache<Integer, NextObjective> pendingNext; | ||
112 | + | ||
111 | 113 | ||
112 | private ScheduledExecutorService groupChecker = | 114 | private ScheduledExecutorService groupChecker = |
113 | Executors.newScheduledThreadPool(2, groupedThreads("onos/pipeliner", | 115 | Executors.newScheduledThreadPool(2, groupedThreads("onos/pipeliner", |
... | @@ -131,6 +133,16 @@ public abstract class AbstractCorsaPipeline extends AbstractHandlerBehaviour imp | ... | @@ -131,6 +133,16 @@ public abstract class AbstractCorsaPipeline extends AbstractHandlerBehaviour imp |
131 | } | 133 | } |
132 | }).build(); | 134 | }).build(); |
133 | 135 | ||
136 | + pendingNext = CacheBuilder.newBuilder() | ||
137 | + .expireAfterWrite(20, TimeUnit.SECONDS) | ||
138 | + .removalListener((RemovalNotification<Integer, NextObjective> notification) -> { | ||
139 | + if (notification.getCause() == RemovalCause.EXPIRED) { | ||
140 | + notification.getValue().context() | ||
141 | + .ifPresent(c -> c.onError(notification.getValue(), | ||
142 | + ObjectiveError.FLOWINSTALLATIONFAILED)); | ||
143 | + } | ||
144 | + }).build(); | ||
145 | + | ||
134 | groupChecker.scheduleAtFixedRate(new GroupChecker(), 0, 500, TimeUnit.MILLISECONDS); | 146 | groupChecker.scheduleAtFixedRate(new GroupChecker(), 0, 500, TimeUnit.MILLISECONDS); |
135 | 147 | ||
136 | coreService = serviceDirectory.get(CoreService.class); | 148 | coreService = serviceDirectory.get(CoreService.class); |
... | @@ -304,6 +316,7 @@ public abstract class AbstractCorsaPipeline extends AbstractHandlerBehaviour imp | ... | @@ -304,6 +316,7 @@ public abstract class AbstractCorsaPipeline extends AbstractHandlerBehaviour imp |
304 | 316 | ||
305 | @Override | 317 | @Override |
306 | public void forward(ForwardingObjective fwd) { | 318 | public void forward(ForwardingObjective fwd) { |
319 | + | ||
307 | Collection<FlowRule> rules; | 320 | Collection<FlowRule> rules; |
308 | FlowRuleOperations.Builder flowBuilder = FlowRuleOperations.builder(); | 321 | FlowRuleOperations.Builder flowBuilder = FlowRuleOperations.builder(); |
309 | 322 | ||
... | @@ -354,16 +367,20 @@ public abstract class AbstractCorsaPipeline extends AbstractHandlerBehaviour imp | ... | @@ -354,16 +367,20 @@ public abstract class AbstractCorsaPipeline extends AbstractHandlerBehaviour imp |
354 | private Collection<FlowRule> processSpecific(ForwardingObjective fwd) { | 367 | private Collection<FlowRule> processSpecific(ForwardingObjective fwd) { |
355 | log.debug("Processing specific forwarding objective"); | 368 | log.debug("Processing specific forwarding objective"); |
356 | TrafficSelector selector = fwd.selector(); | 369 | TrafficSelector selector = fwd.selector(); |
357 | - EthTypeCriterion ethType = | 370 | + EthTypeCriterion ethTypeCriterion = |
358 | (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE); | 371 | (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE); |
359 | - if (ethType != null) { | 372 | + VlanIdCriterion vlanIdCriterion = |
360 | - short et = ethType.ethType().toShort(); | 373 | + (VlanIdCriterion) selector.getCriterion(Criterion.Type.VLAN_VID); |
374 | + if (ethTypeCriterion != null) { | ||
375 | + short et = ethTypeCriterion.ethType().toShort(); | ||
361 | if (et == Ethernet.TYPE_IPV4) { | 376 | if (et == Ethernet.TYPE_IPV4) { |
362 | return processSpecificRoute(fwd); | 377 | return processSpecificRoute(fwd); |
363 | } else if (et == Ethernet.TYPE_VLAN) { | 378 | } else if (et == Ethernet.TYPE_VLAN) { |
364 | /* The ForwardingObjective must specify VLAN ethtype in order to use the Transit Circuit */ | 379 | /* The ForwardingObjective must specify VLAN ethtype in order to use the Transit Circuit */ |
365 | return processSpecificSwitch(fwd); | 380 | return processSpecificSwitch(fwd); |
366 | } | 381 | } |
382 | + } else if (vlanIdCriterion != null) { | ||
383 | + return processSpecificSwitch(fwd); | ||
367 | } | 384 | } |
368 | 385 | ||
369 | fail(fwd, ObjectiveError.UNSUPPORTED); | 386 | fail(fwd, ObjectiveError.UNSUPPORTED); |
... | @@ -464,6 +481,41 @@ public abstract class AbstractCorsaPipeline extends AbstractHandlerBehaviour imp | ... | @@ -464,6 +481,41 @@ public abstract class AbstractCorsaPipeline extends AbstractHandlerBehaviour imp |
464 | //Hook for modifying Route flow rule | 481 | //Hook for modifying Route flow rule |
465 | protected abstract Builder processSpecificRoutingRule(Builder rb); | 482 | protected abstract Builder processSpecificRoutingRule(Builder rb); |
466 | 483 | ||
484 | + protected enum CorsaTrafficTreatmentType { | ||
485 | + /** | ||
486 | + * If the treatment has to be handled as group. | ||
487 | + */ | ||
488 | + GROUP, | ||
489 | + /** | ||
490 | + * If the treatment has to be handled as simple set of actions. | ||
491 | + */ | ||
492 | + ACTIONS | ||
493 | + } | ||
494 | + | ||
495 | + /** | ||
496 | + * Helper class to encapsulate both traffic treatment and | ||
497 | + * type of treatment. | ||
498 | + */ | ||
499 | + protected class CorsaTrafficTreatment { | ||
500 | + | ||
501 | + private CorsaTrafficTreatmentType type; | ||
502 | + private TrafficTreatment trafficTreatment; | ||
503 | + | ||
504 | + public CorsaTrafficTreatment(CorsaTrafficTreatmentType treatmentType, TrafficTreatment trafficTreatment) { | ||
505 | + this.type = treatmentType; | ||
506 | + this.trafficTreatment = trafficTreatment; | ||
507 | + } | ||
508 | + | ||
509 | + public CorsaTrafficTreatmentType type() { | ||
510 | + return type; | ||
511 | + } | ||
512 | + | ||
513 | + public TrafficTreatment treatment() { | ||
514 | + return trafficTreatment; | ||
515 | + } | ||
516 | + | ||
517 | + } | ||
518 | + | ||
467 | @Override | 519 | @Override |
468 | public void next(NextObjective nextObjective) { | 520 | public void next(NextObjective nextObjective) { |
469 | switch (nextObjective.type()) { | 521 | switch (nextObjective.type()) { |
... | @@ -471,20 +523,25 @@ public abstract class AbstractCorsaPipeline extends AbstractHandlerBehaviour imp | ... | @@ -471,20 +523,25 @@ public abstract class AbstractCorsaPipeline extends AbstractHandlerBehaviour imp |
471 | Collection<TrafficTreatment> treatments = nextObjective.next(); | 523 | Collection<TrafficTreatment> treatments = nextObjective.next(); |
472 | if (treatments.size() == 1) { | 524 | if (treatments.size() == 1) { |
473 | TrafficTreatment treatment = treatments.iterator().next(); | 525 | TrafficTreatment treatment = treatments.iterator().next(); |
474 | - treatment = processNextTreatment(treatment); | 526 | + CorsaTrafficTreatment corsaTreatment = processNextTreatment(treatment); |
475 | - GroupBucket bucket = | ||
476 | - DefaultGroupBucket.createIndirectGroupBucket(treatment); | ||
477 | final GroupKey key = new DefaultGroupKey(appKryo.serialize(nextObjective.id())); | 527 | final GroupKey key = new DefaultGroupKey(appKryo.serialize(nextObjective.id())); |
478 | - GroupDescription groupDescription | 528 | + if (corsaTreatment.type() == CorsaTrafficTreatmentType.GROUP) { |
479 | - = new DefaultGroupDescription(deviceId, | 529 | + GroupBucket bucket = DefaultGroupBucket.createIndirectGroupBucket(corsaTreatment.treatment()); |
530 | + GroupBuckets buckets = new GroupBuckets(Collections.singletonList(bucket)); | ||
531 | + // group id == null, let group service determine group id | ||
532 | + GroupDescription groupDescription = new DefaultGroupDescription(deviceId, | ||
480 | GroupDescription.Type.INDIRECT, | 533 | GroupDescription.Type.INDIRECT, |
481 | - new GroupBuckets(Collections | 534 | + buckets, |
482 | - .singletonList(bucket)), | ||
483 | key, | 535 | key, |
484 | - null, // let group service determine group id | 536 | + null, |
485 | nextObjective.appId()); | 537 | nextObjective.appId()); |
486 | groupService.addGroup(groupDescription); | 538 | groupService.addGroup(groupDescription); |
487 | pendingGroups.put(key, nextObjective); | 539 | pendingGroups.put(key, nextObjective); |
540 | + } else if (corsaTreatment.type() == CorsaTrafficTreatmentType.ACTIONS) { | ||
541 | + pendingNext.put(nextObjective.id(), nextObjective); | ||
542 | + flowObjectiveStore.putNextGroup(nextObjective.id(), new CorsaGroup(key)); | ||
543 | + nextObjective.context().ifPresent(context -> context.onSuccess(nextObjective)); | ||
544 | + } | ||
488 | } | 545 | } |
489 | break; | 546 | break; |
490 | case HASHED: | 547 | case HASHED: |
... | @@ -501,8 +558,8 @@ public abstract class AbstractCorsaPipeline extends AbstractHandlerBehaviour imp | ... | @@ -501,8 +558,8 @@ public abstract class AbstractCorsaPipeline extends AbstractHandlerBehaviour imp |
501 | } | 558 | } |
502 | 559 | ||
503 | //Hook for altering the NextObjective treatment | 560 | //Hook for altering the NextObjective treatment |
504 | - protected TrafficTreatment processNextTreatment(TrafficTreatment treatment) { | 561 | + protected CorsaTrafficTreatment processNextTreatment(TrafficTreatment treatment) { |
505 | - return treatment; | 562 | + return new CorsaTrafficTreatment(CorsaTrafficTreatmentType.GROUP, treatment); |
506 | } | 563 | } |
507 | 564 | ||
508 | //Init helper: Table Miss = Drop | 565 | //Init helper: Table Miss = Drop | ... | ... |
... | @@ -30,9 +30,12 @@ import org.onosproject.net.flow.criteria.EthCriterion; | ... | @@ -30,9 +30,12 @@ import org.onosproject.net.flow.criteria.EthCriterion; |
30 | import org.onosproject.net.flow.criteria.IPCriterion; | 30 | import org.onosproject.net.flow.criteria.IPCriterion; |
31 | import org.onosproject.net.flow.criteria.PortCriterion; | 31 | import org.onosproject.net.flow.criteria.PortCriterion; |
32 | import org.onosproject.net.flow.criteria.VlanIdCriterion; | 32 | import org.onosproject.net.flow.criteria.VlanIdCriterion; |
33 | +import org.onosproject.net.flow.instructions.Instruction; | ||
33 | import org.onosproject.net.flow.instructions.L2ModificationInstruction; | 34 | import org.onosproject.net.flow.instructions.L2ModificationInstruction; |
34 | import org.onosproject.net.flowobjective.FilteringObjective; | 35 | import org.onosproject.net.flowobjective.FilteringObjective; |
35 | import org.onosproject.net.flowobjective.ForwardingObjective; | 36 | import org.onosproject.net.flowobjective.ForwardingObjective; |
37 | +import org.onosproject.net.flowobjective.NextObjective; | ||
38 | +import org.onosproject.net.flowobjective.ObjectiveError; | ||
36 | import org.onosproject.net.meter.Band; | 39 | import org.onosproject.net.meter.Band; |
37 | import org.onosproject.net.meter.DefaultBand; | 40 | import org.onosproject.net.meter.DefaultBand; |
38 | import org.onosproject.net.meter.DefaultMeterRequest; | 41 | import org.onosproject.net.meter.DefaultMeterRequest; |
... | @@ -69,9 +72,11 @@ public class CorsaPipelineV3 extends AbstractCorsaPipeline { | ... | @@ -69,9 +72,11 @@ public class CorsaPipelineV3 extends AbstractCorsaPipeline { |
69 | protected MeterId defaultMeterId = null; | 72 | protected MeterId defaultMeterId = null; |
70 | 73 | ||
71 | @Override | 74 | @Override |
72 | - protected TrafficTreatment processNextTreatment(TrafficTreatment treatment) { | 75 | + protected CorsaTrafficTreatment processNextTreatment(TrafficTreatment treatment) { |
73 | TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder(); | 76 | TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder(); |
74 | 77 | ||
78 | + | ||
79 | + | ||
75 | treatment.immediate().stream() | 80 | treatment.immediate().stream() |
76 | .filter(i -> { | 81 | .filter(i -> { |
77 | switch (i.type()) { | 82 | switch (i.type()) { |
... | @@ -87,7 +92,48 @@ public class CorsaPipelineV3 extends AbstractCorsaPipeline { | ... | @@ -87,7 +92,48 @@ public class CorsaPipelineV3 extends AbstractCorsaPipeline { |
87 | return false; | 92 | return false; |
88 | } | 93 | } |
89 | }).forEach(i -> tb.add(i)); | 94 | }).forEach(i -> tb.add(i)); |
90 | - return tb.build(); | 95 | + |
96 | + TrafficTreatment t = tb.build(); | ||
97 | + | ||
98 | + | ||
99 | + boolean isPresentModVlanId = false; | ||
100 | + boolean isPresentModEthSrc = false; | ||
101 | + boolean isPresentModEthDst = false; | ||
102 | + boolean isPresentOutpuPort = false; | ||
103 | + | ||
104 | + for (Instruction instruction : t.immediate()) { | ||
105 | + switch (instruction.type()) { | ||
106 | + case L2MODIFICATION: | ||
107 | + L2ModificationInstruction l2i = (L2ModificationInstruction) instruction; | ||
108 | + if (l2i instanceof L2ModificationInstruction.ModVlanIdInstruction) { | ||
109 | + isPresentModVlanId = true; | ||
110 | + } | ||
111 | + | ||
112 | + if (l2i instanceof L2ModificationInstruction.ModEtherInstruction) { | ||
113 | + L2ModificationInstruction.L2SubType subType = l2i.subtype(); | ||
114 | + if (subType.equals(L2ModificationInstruction.L2SubType.ETH_SRC)) { | ||
115 | + isPresentModEthSrc = true; | ||
116 | + } else if (subType.equals(L2ModificationInstruction.L2SubType.ETH_DST)) { | ||
117 | + isPresentModEthDst = true; | ||
118 | + } | ||
119 | + } | ||
120 | + case OUTPUT: | ||
121 | + isPresentOutpuPort = true; | ||
122 | + default: | ||
123 | + } | ||
124 | + } | ||
125 | + CorsaTrafficTreatmentType type = CorsaTrafficTreatmentType.ACTIONS; | ||
126 | + /** | ||
127 | + * This represents the allowed group for CorsaPipelinev3 | ||
128 | + */ | ||
129 | + if (isPresentModVlanId && | ||
130 | + isPresentModEthSrc && | ||
131 | + isPresentModEthDst && | ||
132 | + isPresentOutpuPort) { | ||
133 | + type = CorsaTrafficTreatmentType.GROUP; | ||
134 | + } | ||
135 | + CorsaTrafficTreatment corsaTreatment = new CorsaTrafficTreatment(type, t); | ||
136 | + return corsaTreatment; | ||
91 | } | 137 | } |
92 | 138 | ||
93 | @Override | 139 | @Override |
... | @@ -115,9 +161,37 @@ public class CorsaPipelineV3 extends AbstractCorsaPipeline { | ... | @@ -115,9 +161,37 @@ public class CorsaPipelineV3 extends AbstractCorsaPipeline { |
115 | .withPriority(fwd.priority()) | 161 | .withPriority(fwd.priority()) |
116 | .forDevice(deviceId) | 162 | .forDevice(deviceId) |
117 | .withSelector(filteredSelector) | 163 | .withSelector(filteredSelector) |
118 | - .withTreatment(fwd.treatment()) | ||
119 | .forTable(VLAN_CIRCUIT_TABLE); | 164 | .forTable(VLAN_CIRCUIT_TABLE); |
120 | 165 | ||
166 | + if (fwd.treatment() != null) { | ||
167 | + ruleBuilder.withTreatment(fwd.treatment()); | ||
168 | + } else { | ||
169 | + if (fwd.nextId() != null) { | ||
170 | + NextObjective nextObjective = pendingNext.getIfPresent(fwd.nextId()); | ||
171 | + if (nextObjective != null) { | ||
172 | + pendingNext.invalidate(fwd.nextId()); | ||
173 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder() | ||
174 | + .setVlanPcp((byte) 0) | ||
175 | + .setQueue(0) | ||
176 | + .meter(defaultMeterId); | ||
177 | + nextObjective.next().forEach(trafficTreatment -> { | ||
178 | + trafficTreatment.allInstructions().forEach(instruction -> { | ||
179 | + treatment.add(instruction); | ||
180 | + }); | ||
181 | + }); | ||
182 | + ruleBuilder.withTreatment(treatment.build()); | ||
183 | + } else { | ||
184 | + log.warn("The group left!"); | ||
185 | + fwd.context().ifPresent(c -> c.onError(fwd, ObjectiveError.GROUPMISSING)); | ||
186 | + return ImmutableSet.of(); | ||
187 | + } | ||
188 | + } else { | ||
189 | + log.warn("Missing NextObjective ID for ForwardingObjective {}", fwd.id()); | ||
190 | + fail(fwd, ObjectiveError.BADPARAMS); | ||
191 | + return ImmutableSet.of(); | ||
192 | + } | ||
193 | + } | ||
194 | + | ||
121 | if (fwd.permanent()) { | 195 | if (fwd.permanent()) { |
122 | ruleBuilder.makePermanent(); | 196 | ruleBuilder.makePermanent(); |
123 | } else { | 197 | } else { | ... | ... |
... | @@ -29,6 +29,7 @@ import org.onosproject.net.flow.TrafficTreatment; | ... | @@ -29,6 +29,7 @@ import org.onosproject.net.flow.TrafficTreatment; |
29 | import org.onosproject.net.flow.criteria.Criterion; | 29 | import org.onosproject.net.flow.criteria.Criterion; |
30 | import org.onosproject.net.flow.criteria.IPCriterion; | 30 | import org.onosproject.net.flow.criteria.IPCriterion; |
31 | import org.onosproject.net.flow.criteria.IPProtocolCriterion; | 31 | import org.onosproject.net.flow.criteria.IPProtocolCriterion; |
32 | +import org.onosproject.net.flow.instructions.Instruction; | ||
32 | import org.onosproject.net.flow.instructions.Instructions; | 33 | import org.onosproject.net.flow.instructions.Instructions; |
33 | import org.onosproject.net.flow.instructions.L2ModificationInstruction; | 34 | import org.onosproject.net.flow.instructions.L2ModificationInstruction; |
34 | import org.onosproject.net.flowobjective.ForwardingObjective; | 35 | import org.onosproject.net.flowobjective.ForwardingObjective; |
... | @@ -226,9 +227,8 @@ public class CorsaPipelineV39 extends CorsaPipelineV3 { | ... | @@ -226,9 +227,8 @@ public class CorsaPipelineV39 extends CorsaPipelineV3 { |
226 | } | 227 | } |
227 | 228 | ||
228 | @Override | 229 | @Override |
229 | - protected TrafficTreatment processNextTreatment(TrafficTreatment treatment) { | 230 | + protected CorsaTrafficTreatment processNextTreatment(TrafficTreatment treatment) { |
230 | TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder(); | 231 | TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder(); |
231 | - tb.add(Instructions.popVlan()); | ||
232 | treatment.immediate().stream() | 232 | treatment.immediate().stream() |
233 | .filter(i -> { | 233 | .filter(i -> { |
234 | switch (i.type()) { | 234 | switch (i.type()) { |
... | @@ -236,7 +236,6 @@ public class CorsaPipelineV39 extends CorsaPipelineV3 { | ... | @@ -236,7 +236,6 @@ public class CorsaPipelineV39 extends CorsaPipelineV3 { |
236 | L2ModificationInstruction l2i = (L2ModificationInstruction) i; | 236 | L2ModificationInstruction l2i = (L2ModificationInstruction) i; |
237 | if (l2i.subtype() == VLAN_ID || | 237 | if (l2i.subtype() == VLAN_ID || |
238 | l2i.subtype() == VLAN_POP || | 238 | l2i.subtype() == VLAN_POP || |
239 | - l2i.subtype() == VLAN_POP || | ||
240 | l2i.subtype() == ETH_DST || | 239 | l2i.subtype() == ETH_DST || |
241 | l2i.subtype() == ETH_SRC) { | 240 | l2i.subtype() == ETH_SRC) { |
242 | return true; | 241 | return true; |
... | @@ -247,6 +246,51 @@ public class CorsaPipelineV39 extends CorsaPipelineV3 { | ... | @@ -247,6 +246,51 @@ public class CorsaPipelineV39 extends CorsaPipelineV3 { |
247 | return false; | 246 | return false; |
248 | } | 247 | } |
249 | }).forEach(i -> tb.add(i)); | 248 | }).forEach(i -> tb.add(i)); |
250 | - return tb.build(); | 249 | + |
250 | + TrafficTreatment t = tb.build(); | ||
251 | + | ||
252 | + boolean isPresentModVlanId = false; | ||
253 | + boolean isPresentModEthSrc = false; | ||
254 | + boolean isPresentModEthDst = false; | ||
255 | + boolean isPresentOutpuPort = false; | ||
256 | + | ||
257 | + for (Instruction instruction : t.immediate()) { | ||
258 | + switch (instruction.type()) { | ||
259 | + case L2MODIFICATION: | ||
260 | + L2ModificationInstruction l2i = (L2ModificationInstruction) instruction; | ||
261 | + if (l2i instanceof L2ModificationInstruction.ModVlanIdInstruction) { | ||
262 | + isPresentModVlanId = true; | ||
263 | + } | ||
264 | + | ||
265 | + if (l2i instanceof L2ModificationInstruction.ModEtherInstruction) { | ||
266 | + L2ModificationInstruction.L2SubType subType = l2i.subtype(); | ||
267 | + if (subType.equals(L2ModificationInstruction.L2SubType.ETH_SRC)) { | ||
268 | + isPresentModEthSrc = true; | ||
269 | + } else if (subType.equals(L2ModificationInstruction.L2SubType.ETH_DST)) { | ||
270 | + isPresentModEthDst = true; | ||
271 | + } | ||
272 | + } | ||
273 | + case OUTPUT: | ||
274 | + isPresentOutpuPort = true; | ||
275 | + default: | ||
276 | + } | ||
277 | + } | ||
278 | + CorsaTrafficTreatmentType type = CorsaTrafficTreatmentType.ACTIONS; | ||
279 | + /** | ||
280 | + * These are the allowed groups for CorsaPipelinev39 | ||
281 | + */ | ||
282 | + if (isPresentModVlanId && isPresentModEthSrc && isPresentModEthDst && isPresentOutpuPort) { | ||
283 | + type = CorsaTrafficTreatmentType.GROUP; | ||
284 | + | ||
285 | + } else if ((!isPresentModVlanId && isPresentModEthSrc && isPresentModEthDst && isPresentOutpuPort) || | ||
286 | + (!isPresentModVlanId && !isPresentModEthSrc && isPresentModEthDst && isPresentOutpuPort) || | ||
287 | + (!isPresentModVlanId && !isPresentModEthSrc && !isPresentModEthDst && isPresentOutpuPort)) { | ||
288 | + type = CorsaTrafficTreatmentType.GROUP; | ||
289 | + TrafficTreatment.Builder tb2 = DefaultTrafficTreatment.builder(t); | ||
290 | + tb2.add(Instructions.popVlan()); | ||
291 | + t = tb2.build(); | ||
292 | + } | ||
293 | + CorsaTrafficTreatment corsaTreatment = new CorsaTrafficTreatment(type, t); | ||
294 | + return corsaTreatment; | ||
251 | } | 295 | } |
252 | } | 296 | } | ... | ... |
-
Please register or login to post a comment