Committed by
Gerrit Code Review
Add MPLS encapsulation behaviour ONOS-3467
- MPLS encapsulation using constraint - New MPLS encapsulation test - Fix VLAN encapsulation test Change-Id: I94670bcd51a95a0272f786681e51d6785a56c4f5
Showing
8 changed files
with
366 additions
and
46 deletions
... | @@ -31,7 +31,11 @@ import java.util.Optional; | ... | @@ -31,7 +31,11 @@ import java.util.Optional; |
31 | 31 | ||
32 | /** | 32 | /** |
33 | * Installs MPLS intents. | 33 | * Installs MPLS intents. |
34 | + * | ||
35 | + * @deprecated in Goldeneye Release, in favour of encapsulation | ||
36 | + * constraint {@link org.onosproject.net.intent.constraint.EncapsulationConstraint} | ||
34 | */ | 37 | */ |
38 | +@Deprecated | ||
35 | @Command(scope = "onos", name = "add-mpls-intent", description = "Installs mpls connectivity intent") | 39 | @Command(scope = "onos", name = "add-mpls-intent", description = "Installs mpls connectivity intent") |
36 | public class AddMplsIntent extends ConnectivityIntentCommand { | 40 | public class AddMplsIntent extends ConnectivityIntentCommand { |
37 | 41 | ... | ... |
... | @@ -34,8 +34,14 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -34,8 +34,14 @@ import static com.google.common.base.Preconditions.checkNotNull; |
34 | 34 | ||
35 | /** | 35 | /** |
36 | * Abstraction of MPLS label-switched connectivity. | 36 | * Abstraction of MPLS label-switched connectivity. |
37 | + * | ||
38 | + * @deprecated in Goldeneye Release, in favour of encapsulation | ||
39 | + * constraint {@link org.onosproject.net.intent.constraint.EncapsulationConstraint} | ||
40 | + * with Encasulation type {@link org.onosproject.net.EncapsulationType} MPLS. | ||
41 | + * | ||
37 | */ | 42 | */ |
38 | @Beta | 43 | @Beta |
44 | +@Deprecated | ||
39 | public final class MplsIntent extends ConnectivityIntent { | 45 | public final class MplsIntent extends ConnectivityIntent { |
40 | 46 | ||
41 | private final ConnectPoint ingressPoint; | 47 | private final ConnectPoint ingressPoint; | ... | ... |
... | @@ -30,8 +30,12 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -30,8 +30,12 @@ import static com.google.common.base.Preconditions.checkNotNull; |
30 | 30 | ||
31 | /** | 31 | /** |
32 | * Abstraction of explicit MPLS label-switched path. | 32 | * Abstraction of explicit MPLS label-switched path. |
33 | + * | ||
34 | + * @deprecated in Goldeneye Release, in favour of encapsulation | ||
35 | + * constraint {@link org.onosproject.net.intent.constraint.EncapsulationConstraint} | ||
33 | */ | 36 | */ |
34 | @Beta | 37 | @Beta |
38 | +@Deprecated | ||
35 | public final class MplsPathIntent extends PathIntent { | 39 | public final class MplsPathIntent extends PathIntent { |
36 | 40 | ||
37 | private final Optional<MplsLabel> ingressLabel; | 41 | private final Optional<MplsLabel> ingressLabel; | ... | ... |
... | @@ -36,7 +36,11 @@ import org.onosproject.net.intent.MplsPathIntent; | ... | @@ -36,7 +36,11 @@ import org.onosproject.net.intent.MplsPathIntent; |
36 | import org.onosproject.net.provider.ProviderId; | 36 | import org.onosproject.net.provider.ProviderId; |
37 | import org.onosproject.net.resource.link.LinkResourceAllocations; | 37 | import org.onosproject.net.resource.link.LinkResourceAllocations; |
38 | 38 | ||
39 | - | 39 | +/** |
40 | + * @deprecated in Goldeneye Release, in favour of encapsulation | ||
41 | + * constraint {@link org.onosproject.net.intent.constraint.EncapsulationConstraint} | ||
42 | + */ | ||
43 | +@Deprecated | ||
40 | @Component(immediate = true) | 44 | @Component(immediate = true) |
41 | public class MplsIntentCompiler extends ConnectivityIntentCompiler<MplsIntent> { | 45 | public class MplsIntentCompiler extends ConnectivityIntentCompiler<MplsIntent> { |
42 | 46 | ... | ... |
... | @@ -68,6 +68,11 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -68,6 +68,11 @@ import static com.google.common.base.Preconditions.checkNotNull; |
68 | import static org.onosproject.net.LinkKey.linkKey; | 68 | import static org.onosproject.net.LinkKey.linkKey; |
69 | import static org.slf4j.LoggerFactory.getLogger; | 69 | import static org.slf4j.LoggerFactory.getLogger; |
70 | 70 | ||
71 | +/** | ||
72 | + * @deprecated in Goldeneye Release, in favour of encapsulation | ||
73 | + * constraint {@link org.onosproject.net.intent.constraint.EncapsulationConstraint} | ||
74 | + */ | ||
75 | +@Deprecated | ||
71 | @Component(immediate = true) | 76 | @Component(immediate = true) |
72 | public class MplsPathIntentCompiler implements IntentCompiler<MplsPathIntent> { | 77 | public class MplsPathIntentCompiler implements IntentCompiler<MplsPathIntent> { |
73 | 78 | ... | ... |
... | @@ -25,6 +25,9 @@ import java.util.Set; | ... | @@ -25,6 +25,9 @@ import java.util.Set; |
25 | import java.util.stream.Collectors; | 25 | import java.util.stream.Collectors; |
26 | import java.util.stream.Stream; | 26 | import java.util.stream.Stream; |
27 | 27 | ||
28 | +import org.onlab.packet.EthType; | ||
29 | +import org.onlab.packet.Ethernet; | ||
30 | +import org.onlab.packet.MplsLabel; | ||
28 | import org.onlab.packet.VlanId; | 31 | import org.onlab.packet.VlanId; |
29 | import org.onosproject.net.ConnectPoint; | 32 | import org.onosproject.net.ConnectPoint; |
30 | import org.onosproject.net.DeviceId; | 33 | import org.onosproject.net.DeviceId; |
... | @@ -35,12 +38,16 @@ import org.onosproject.net.flow.DefaultTrafficTreatment; | ... | @@ -35,12 +38,16 @@ import org.onosproject.net.flow.DefaultTrafficTreatment; |
35 | import org.onosproject.net.flow.TrafficSelector; | 38 | import org.onosproject.net.flow.TrafficSelector; |
36 | import org.onosproject.net.flow.TrafficTreatment; | 39 | import org.onosproject.net.flow.TrafficTreatment; |
37 | import org.onosproject.net.flow.criteria.Criterion; | 40 | import org.onosproject.net.flow.criteria.Criterion; |
41 | +import org.onosproject.net.flow.criteria.EthTypeCriterion; | ||
42 | +import org.onosproject.net.flow.criteria.MplsCriterion; | ||
38 | import org.onosproject.net.flow.criteria.VlanIdCriterion; | 43 | import org.onosproject.net.flow.criteria.VlanIdCriterion; |
44 | +import org.onosproject.net.flow.instructions.Instruction; | ||
39 | import org.onosproject.net.flow.instructions.L2ModificationInstruction; | 45 | import org.onosproject.net.flow.instructions.L2ModificationInstruction; |
40 | import org.onosproject.net.intent.PathIntent; | 46 | import org.onosproject.net.intent.PathIntent; |
41 | import org.onosproject.net.intent.constraint.EncapsulationConstraint; | 47 | import org.onosproject.net.intent.constraint.EncapsulationConstraint; |
42 | import org.onosproject.net.intent.impl.IntentCompilationException; | 48 | import org.onosproject.net.intent.impl.IntentCompilationException; |
43 | import org.onosproject.net.newresource.Resource; | 49 | import org.onosproject.net.newresource.Resource; |
50 | +import org.onosproject.net.newresource.ResourceAllocation; | ||
44 | import org.onosproject.net.newresource.ResourceService; | 51 | import org.onosproject.net.newresource.ResourceService; |
45 | import org.onosproject.net.newresource.Resources; | 52 | import org.onosproject.net.newresource.Resources; |
46 | import org.slf4j.Logger; | 53 | import org.slf4j.Logger; |
... | @@ -227,6 +234,185 @@ public class PathCompiler<T> { | ... | @@ -227,6 +234,185 @@ public class PathCompiler<T> { |
227 | } | 234 | } |
228 | } | 235 | } |
229 | 236 | ||
237 | + private Map<LinkKey, MplsLabel> assignMplsLabel(PathCompilerCreateFlow creator, PathIntent intent) { | ||
238 | + Set<LinkKey> linkRequest = | ||
239 | + Sets.newHashSetWithExpectedSize(intent.path() | ||
240 | + .links().size() - 2); | ||
241 | + for (int i = 1; i <= intent.path().links().size() - 2; i++) { | ||
242 | + LinkKey link = linkKey(intent.path().links().get(i)); | ||
243 | + linkRequest.add(link); | ||
244 | + // add the inverse link. I want that the VLANID is reserved both for | ||
245 | + // the direct and inverse link | ||
246 | + linkRequest.add(linkKey(link.dst(), link.src())); | ||
247 | + } | ||
248 | + | ||
249 | + Map<LinkKey, MplsLabel> labels = findMplsLabels(creator, linkRequest); | ||
250 | + if (labels.isEmpty()) { | ||
251 | + throw new IntentCompilationException("No available MPLS Label"); | ||
252 | + } | ||
253 | + | ||
254 | + // for short term solution: same label is used for both directions | ||
255 | + // TODO: introduce the concept of Tx and Rx resources of a port | ||
256 | + Set<Resource> resources = labels.entrySet().stream() | ||
257 | + .flatMap(x -> Stream.of( | ||
258 | + Resources.discrete(x.getKey().src().deviceId(), x.getKey().src().port(), x.getValue()) | ||
259 | + .resource(), | ||
260 | + Resources.discrete(x.getKey().dst().deviceId(), x.getKey().dst().port(), x.getValue()) | ||
261 | + .resource() | ||
262 | + )) | ||
263 | + .collect(Collectors.toSet()); | ||
264 | + List<ResourceAllocation> allocations = | ||
265 | + creator.resourceService().allocate(intent.id(), ImmutableList.copyOf(resources)); | ||
266 | + if (allocations.isEmpty()) { | ||
267 | + Collections.emptyMap(); | ||
268 | + } | ||
269 | + | ||
270 | + return labels; | ||
271 | + } | ||
272 | + | ||
273 | + private Map<LinkKey, MplsLabel> findMplsLabels(PathCompilerCreateFlow creator, Set<LinkKey> links) { | ||
274 | + Map<LinkKey, MplsLabel> labels = new HashMap<>(); | ||
275 | + for (LinkKey link : links) { | ||
276 | + Set<MplsLabel> forward = findMplsLabel(creator, link.src()); | ||
277 | + Set<MplsLabel> backward = findMplsLabel(creator, link.dst()); | ||
278 | + Set<MplsLabel> common = Sets.intersection(forward, backward); | ||
279 | + if (common.isEmpty()) { | ||
280 | + continue; | ||
281 | + } | ||
282 | + labels.put(link, common.iterator().next()); | ||
283 | + } | ||
284 | + | ||
285 | + return labels; | ||
286 | + } | ||
287 | + | ||
288 | + private Set<MplsLabel> findMplsLabel(PathCompilerCreateFlow creator, ConnectPoint cp) { | ||
289 | + return creator.resourceService().getAvailableResourceValues( | ||
290 | + Resources.discrete(cp.deviceId(), cp.port()).id(), | ||
291 | + MplsLabel.class); | ||
292 | + } | ||
293 | + | ||
294 | + private void manageMplsEncap(PathCompilerCreateFlow<T> creator, List<T> flows, | ||
295 | + List<DeviceId> devices, | ||
296 | + PathIntent intent) { | ||
297 | + Map<LinkKey, MplsLabel> mplsLabels = assignMplsLabel(creator, intent); | ||
298 | + | ||
299 | + Iterator<Link> links = intent.path().links().iterator(); | ||
300 | + Link srcLink = links.next(); | ||
301 | + | ||
302 | + Link link = links.next(); | ||
303 | + // List of flow rules to be installed | ||
304 | + | ||
305 | + // Ingress traffic | ||
306 | + MplsLabel mplsLabel = mplsLabels.get(linkKey(link)); | ||
307 | + if (mplsLabel == null) { | ||
308 | + throw new IntentCompilationException("No available MPLS Label for " + link); | ||
309 | + } | ||
310 | + MplsLabel prevMplsLabel = mplsLabel; | ||
311 | + | ||
312 | + Optional<MplsCriterion> mplsCriterion = intent.selector().criteria() | ||
313 | + .stream().filter(criterion -> criterion.type() == Criterion.Type.MPLS_LABEL) | ||
314 | + .map(criterion -> (MplsCriterion) criterion) | ||
315 | + .findAny(); | ||
316 | + | ||
317 | + //Push MPLS if selector does not include MPLS | ||
318 | + TrafficTreatment.Builder treatBuilder = DefaultTrafficTreatment.builder(); | ||
319 | + if (!mplsCriterion.isPresent()) { | ||
320 | + treatBuilder.pushMpls(); | ||
321 | + } | ||
322 | + //Tag the traffic with the new encapsulation MPLS label | ||
323 | + treatBuilder.setMpls(mplsLabel); | ||
324 | + creator.createFlow(intent.selector(), treatBuilder.build(), | ||
325 | + srcLink.dst(), link.src(), intent.priority(), true, flows, devices); | ||
326 | + | ||
327 | + ConnectPoint prev = link.dst(); | ||
328 | + | ||
329 | + while (links.hasNext()) { | ||
330 | + | ||
331 | + link = links.next(); | ||
332 | + | ||
333 | + if (links.hasNext()) { | ||
334 | + // Transit traffic | ||
335 | + MplsLabel transitMplsLabel = mplsLabels.get(linkKey(link)); | ||
336 | + if (transitMplsLabel == null) { | ||
337 | + throw new IntentCompilationException("No available MPLS label for " + link); | ||
338 | + } | ||
339 | + prevMplsLabel = transitMplsLabel; | ||
340 | + | ||
341 | + TrafficSelector transitSelector = DefaultTrafficSelector.builder() | ||
342 | + .matchInPort(prev.port()) | ||
343 | + .matchEthType(Ethernet.MPLS_UNICAST) | ||
344 | + .matchMplsLabel(prevMplsLabel).build(); | ||
345 | + | ||
346 | + TrafficTreatment.Builder transitTreat = DefaultTrafficTreatment.builder(); | ||
347 | + | ||
348 | + // Set the new MPLS Label only if the previous one is different | ||
349 | + if (!prevMplsLabel.equals(transitMplsLabel)) { | ||
350 | + transitTreat.setMpls(transitMplsLabel); | ||
351 | + } | ||
352 | + creator.createFlow(transitSelector, | ||
353 | + transitTreat.build(), prev, link.src(), intent.priority(), true, flows, devices); | ||
354 | + prev = link.dst(); | ||
355 | + } else { | ||
356 | + TrafficSelector.Builder egressSelector = DefaultTrafficSelector.builder() | ||
357 | + .matchInPort(prev.port()) | ||
358 | + .matchEthType(Ethernet.MPLS_UNICAST) | ||
359 | + .matchMplsLabel(prevMplsLabel); | ||
360 | + TrafficTreatment.Builder egressTreat = DefaultTrafficTreatment.builder(intent.treatment()); | ||
361 | + | ||
362 | + // Egress traffic | ||
363 | + // check if the treatement is popVlan or setVlan (rewrite), | ||
364 | + // than selector needs to match any VlanId | ||
365 | + for (Instruction instruct : intent.treatment().allInstructions()) { | ||
366 | + if (instruct instanceof L2ModificationInstruction) { | ||
367 | + L2ModificationInstruction l2Mod = (L2ModificationInstruction) instruct; | ||
368 | + if (l2Mod.subtype() == L2ModificationInstruction.L2SubType.VLAN_PUSH) { | ||
369 | + break; | ||
370 | + } | ||
371 | + if (l2Mod.subtype() == L2ModificationInstruction.L2SubType.VLAN_POP || | ||
372 | + l2Mod.subtype() == L2ModificationInstruction.L2SubType.VLAN_ID) { | ||
373 | + egressSelector.matchVlanId(VlanId.ANY); | ||
374 | + } | ||
375 | + } | ||
376 | + } | ||
377 | + | ||
378 | + if (mplsCriterion.isPresent()) { | ||
379 | + egressTreat.setMpls(mplsCriterion.get().label()); | ||
380 | + } else { | ||
381 | + egressTreat.popMpls(outputEthType(intent.selector())); | ||
382 | + } | ||
383 | + | ||
384 | + | ||
385 | + if (mplsCriterion.isPresent()) { | ||
386 | + egressTreat.setMpls(mplsCriterion.get().label()); | ||
387 | + } else { | ||
388 | + egressTreat.popVlan(); | ||
389 | + } | ||
390 | + | ||
391 | + creator.createFlow(egressSelector.build(), | ||
392 | + egressTreat.build(), prev, link.src(), intent.priority(), true, flows, devices); | ||
393 | + } | ||
394 | + | ||
395 | + } | ||
396 | + | ||
397 | + } | ||
398 | + | ||
399 | + private MplsLabel getMplsLabel(Map<LinkKey, MplsLabel> labels, LinkKey link) { | ||
400 | + return labels.get(link); | ||
401 | + } | ||
402 | + | ||
403 | + // if the ingress ethertype is defined, the egress traffic | ||
404 | + // will be use that value, otherwise the IPv4 ethertype is used. | ||
405 | + private EthType outputEthType(TrafficSelector selector) { | ||
406 | + Criterion c = selector.getCriterion(Criterion.Type.ETH_TYPE); | ||
407 | + if (c != null && c instanceof EthTypeCriterion) { | ||
408 | + EthTypeCriterion ethertype = (EthTypeCriterion) c; | ||
409 | + return ethertype.ethType(); | ||
410 | + } else { | ||
411 | + return EthType.EtherType.IPV4.ethType(); | ||
412 | + } | ||
413 | + } | ||
414 | + | ||
415 | + | ||
230 | /** | 416 | /** |
231 | * Compiles an intent down to flows. | 417 | * Compiles an intent down to flows. |
232 | * | 418 | * |
... | @@ -263,7 +449,10 @@ public class PathCompiler<T> { | ... | @@ -263,7 +449,10 @@ public class PathCompiler<T> { |
263 | switch (type) { | 449 | switch (type) { |
264 | case VLAN: | 450 | case VLAN: |
265 | manageVlanEncap(creator, flows, devices, intent); | 451 | manageVlanEncap(creator, flows, devices, intent); |
266 | - // TODO: implement MPLS case here | 452 | + break; |
453 | + case MPLS: | ||
454 | + manageMplsEncap(creator, flows, devices, intent); | ||
455 | + break; | ||
267 | default: | 456 | default: |
268 | // Nothing to do | 457 | // Nothing to do |
269 | } | 458 | } | ... | ... |
... | @@ -15,10 +15,7 @@ | ... | @@ -15,10 +15,7 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.net.intent.impl.compiler; | 16 | package org.onosproject.net.intent.impl.compiler; |
17 | 17 | ||
18 | -import java.util.LinkedList; | 18 | +import com.google.common.collect.ImmutableList; |
19 | -import java.util.List; | ||
20 | -import java.util.Set; | ||
21 | - | ||
22 | import org.apache.felix.scr.annotations.Activate; | 19 | import org.apache.felix.scr.annotations.Activate; |
23 | import org.apache.felix.scr.annotations.Component; | 20 | import org.apache.felix.scr.annotations.Component; |
24 | import org.apache.felix.scr.annotations.Deactivate; | 21 | import org.apache.felix.scr.annotations.Deactivate; |
... | @@ -42,10 +39,13 @@ import org.onosproject.net.newresource.ResourceService; | ... | @@ -42,10 +39,13 @@ import org.onosproject.net.newresource.ResourceService; |
42 | import org.onosproject.net.resource.link.LinkResourceAllocations; | 39 | import org.onosproject.net.resource.link.LinkResourceAllocations; |
43 | import org.slf4j.Logger; | 40 | import org.slf4j.Logger; |
44 | 41 | ||
45 | -import com.google.common.collect.ImmutableList; | 42 | +import java.util.LinkedList; |
43 | +import java.util.List; | ||
44 | +import java.util.Set; | ||
46 | 45 | ||
47 | import static org.slf4j.LoggerFactory.getLogger; | 46 | import static org.slf4j.LoggerFactory.getLogger; |
48 | 47 | ||
48 | + | ||
49 | @Component(immediate = true) | 49 | @Component(immediate = true) |
50 | public class PathIntentCompiler | 50 | public class PathIntentCompiler |
51 | extends PathCompiler<FlowRule> | 51 | extends PathCompiler<FlowRule> |
... | @@ -84,6 +84,7 @@ public class PathIntentCompiler | ... | @@ -84,6 +84,7 @@ public class PathIntentCompiler |
84 | List<DeviceId> devices = new LinkedList<>(); | 84 | List<DeviceId> devices = new LinkedList<>(); |
85 | compile(this, intent, rules, devices); | 85 | compile(this, intent, rules, devices); |
86 | 86 | ||
87 | + | ||
87 | return ImmutableList.of(new FlowRuleIntent(appId, null, rules, intent.resources())); | 88 | return ImmutableList.of(new FlowRuleIntent(appId, null, rules, intent.resources())); |
88 | } | 89 | } |
89 | 90 | ||
... | @@ -97,12 +98,14 @@ public class PathIntentCompiler | ... | @@ -97,12 +98,14 @@ public class PathIntentCompiler |
97 | return resourceService; | 98 | return resourceService; |
98 | } | 99 | } |
99 | 100 | ||
101 | + | ||
100 | @Override | 102 | @Override |
101 | public void createFlow(TrafficSelector originalSelector, TrafficTreatment originalTreatment, | 103 | public void createFlow(TrafficSelector originalSelector, TrafficTreatment originalTreatment, |
102 | ConnectPoint ingress, ConnectPoint egress, | 104 | ConnectPoint ingress, ConnectPoint egress, |
103 | int priority, boolean applyTreatment, | 105 | int priority, boolean applyTreatment, |
104 | List<FlowRule> rules, | 106 | List<FlowRule> rules, |
105 | List<DeviceId> devices) { | 107 | List<DeviceId> devices) { |
108 | + | ||
106 | TrafficSelector selector = DefaultTrafficSelector.builder(originalSelector) | 109 | TrafficSelector selector = DefaultTrafficSelector.builder(originalSelector) |
107 | .matchInPort(ingress.port()) | 110 | .matchInPort(ingress.port()) |
108 | .build(); | 111 | .build(); |
... | @@ -123,5 +126,6 @@ public class PathIntentCompiler | ... | @@ -123,5 +126,6 @@ public class PathIntentCompiler |
123 | .fromApp(appId) | 126 | .fromApp(appId) |
124 | .makePermanent() | 127 | .makePermanent() |
125 | .build()); | 128 | .build()); |
129 | + | ||
126 | } | 130 | } |
127 | } | 131 | } | ... | ... |
... | @@ -19,6 +19,8 @@ import com.google.common.collect.ImmutableList; | ... | @@ -19,6 +19,8 @@ import com.google.common.collect.ImmutableList; |
19 | import org.junit.After; | 19 | import org.junit.After; |
20 | import org.junit.Before; | 20 | import org.junit.Before; |
21 | import org.junit.Test; | 21 | import org.junit.Test; |
22 | +import org.onlab.packet.Ethernet; | ||
23 | +import org.onlab.packet.MplsLabel; | ||
22 | import org.onlab.packet.VlanId; | 24 | import org.onlab.packet.VlanId; |
23 | import org.onosproject.TestApplicationId; | 25 | import org.onosproject.TestApplicationId; |
24 | import org.onosproject.cfg.ComponentConfigAdapter; | 26 | import org.onosproject.cfg.ComponentConfigAdapter; |
... | @@ -28,6 +30,7 @@ import org.onosproject.core.IdGenerator; | ... | @@ -28,6 +30,7 @@ import org.onosproject.core.IdGenerator; |
28 | import org.onosproject.net.ConnectPoint; | 30 | import org.onosproject.net.ConnectPoint; |
29 | import org.onosproject.net.DefaultLink; | 31 | import org.onosproject.net.DefaultLink; |
30 | import org.onosproject.net.DefaultPath; | 32 | import org.onosproject.net.DefaultPath; |
33 | +import org.onosproject.net.DeviceId; | ||
31 | import org.onosproject.net.EncapsulationType; | 34 | import org.onosproject.net.EncapsulationType; |
32 | import org.onosproject.net.Link; | 35 | import org.onosproject.net.Link; |
33 | import org.onosproject.net.flow.DefaultTrafficSelector; | 36 | import org.onosproject.net.flow.DefaultTrafficSelector; |
... | @@ -52,14 +55,18 @@ import java.util.List; | ... | @@ -52,14 +55,18 @@ import java.util.List; |
52 | import java.util.Set; | 55 | import java.util.Set; |
53 | import java.util.stream.Collectors; | 56 | import java.util.stream.Collectors; |
54 | 57 | ||
55 | -import static org.easymock.EasyMock.*; | 58 | +import static org.easymock.EasyMock.createMock; |
59 | +import static org.easymock.EasyMock.expect; | ||
60 | +import static org.easymock.EasyMock.replay; | ||
56 | import static org.hamcrest.MatcherAssert.assertThat; | 61 | import static org.hamcrest.MatcherAssert.assertThat; |
57 | import static org.hamcrest.Matchers.hasSize; | 62 | import static org.hamcrest.Matchers.hasSize; |
58 | import static org.hamcrest.Matchers.is; | 63 | import static org.hamcrest.Matchers.is; |
59 | import static org.hamcrest.number.OrderingComparison.greaterThan; | 64 | import static org.hamcrest.number.OrderingComparison.greaterThan; |
60 | import static org.onosproject.net.DefaultEdgeLink.createEdgeLink; | 65 | import static org.onosproject.net.DefaultEdgeLink.createEdgeLink; |
61 | import static org.onosproject.net.Link.Type.DIRECT; | 66 | import static org.onosproject.net.Link.Type.DIRECT; |
62 | -import static org.onosproject.net.NetTestTools.*; | 67 | +import static org.onosproject.net.NetTestTools.APP_ID; |
68 | +import static org.onosproject.net.NetTestTools.PID; | ||
69 | +import static org.onosproject.net.NetTestTools.connectPoint; | ||
63 | 70 | ||
64 | /** | 71 | /** |
65 | * Unit tests for PathIntentCompiler. | 72 | * Unit tests for PathIntentCompiler. |
... | @@ -99,8 +106,9 @@ public class PathIntentCompilerTest { | ... | @@ -99,8 +106,9 @@ public class PathIntentCompilerTest { |
99 | ); | 106 | ); |
100 | private final int hops = links.size() - 1; | 107 | private final int hops = links.size() - 1; |
101 | private PathIntent intent; | 108 | private PathIntent intent; |
102 | - private PathIntent constraintIntent; | 109 | + private PathIntent constraintVlanIntent; |
103 | private PathIntent constrainIngressEgressVlanIntent; | 110 | private PathIntent constrainIngressEgressVlanIntent; |
111 | + private PathIntent constraintMplsIntent; | ||
104 | 112 | ||
105 | /** | 113 | /** |
106 | * Configures objects used in all the test cases. | 114 | * Configures objects used in all the test cases. |
... | @@ -123,8 +131,9 @@ public class PathIntentCompilerTest { | ... | @@ -123,8 +131,9 @@ public class PathIntentCompilerTest { |
123 | .priority(PRIORITY) | 131 | .priority(PRIORITY) |
124 | .path(new DefaultPath(pid, links, hops)) | 132 | .path(new DefaultPath(pid, links, hops)) |
125 | .build(); | 133 | .build(); |
134 | + | ||
126 | //Intent with VLAN encap without egress VLAN | 135 | //Intent with VLAN encap without egress VLAN |
127 | - constraintIntent = PathIntent.builder() | 136 | + constraintVlanIntent = PathIntent.builder() |
128 | .appId(APP_ID) | 137 | .appId(APP_ID) |
129 | .selector(selector) | 138 | .selector(selector) |
130 | .treatment(treatment) | 139 | .treatment(treatment) |
... | @@ -132,6 +141,7 @@ public class PathIntentCompilerTest { | ... | @@ -132,6 +141,7 @@ public class PathIntentCompilerTest { |
132 | .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN))) | 141 | .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN))) |
133 | .path(new DefaultPath(pid, links, hops)) | 142 | .path(new DefaultPath(pid, links, hops)) |
134 | .build(); | 143 | .build(); |
144 | + | ||
135 | //Intent with VLAN encap with ingress and egress VLAN | 145 | //Intent with VLAN encap with ingress and egress VLAN |
136 | constrainIngressEgressVlanIntent = PathIntent.builder() | 146 | constrainIngressEgressVlanIntent = PathIntent.builder() |
137 | .appId(APP_ID) | 147 | .appId(APP_ID) |
... | @@ -141,6 +151,15 @@ public class PathIntentCompilerTest { | ... | @@ -141,6 +151,15 @@ public class PathIntentCompilerTest { |
141 | .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN))) | 151 | .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN))) |
142 | .path(new DefaultPath(pid, links, hops)) | 152 | .path(new DefaultPath(pid, links, hops)) |
143 | .build(); | 153 | .build(); |
154 | + | ||
155 | + constraintMplsIntent = PathIntent.builder() | ||
156 | + .appId(APP_ID) | ||
157 | + .selector(selector) | ||
158 | + .treatment(treatment) | ||
159 | + .priority(PRIORITY) | ||
160 | + .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.MPLS))) | ||
161 | + .path(new DefaultPath(pid, links, hops)) | ||
162 | + .build(); | ||
144 | intentExtensionService = createMock(IntentExtensionService.class); | 163 | intentExtensionService = createMock(IntentExtensionService.class); |
145 | intentExtensionService.registerCompiler(PathIntent.class, sut); | 164 | intentExtensionService.registerCompiler(PathIntent.class, sut); |
146 | intentExtensionService.unregisterCompiler(PathIntent.class); | 165 | intentExtensionService.unregisterCompiler(PathIntent.class); |
... | @@ -179,34 +198,32 @@ public class PathIntentCompilerTest { | ... | @@ -179,34 +198,32 @@ public class PathIntentCompilerTest { |
179 | .filter(x -> x.deviceId().equals(d1p0.deviceId())) | 198 | .filter(x -> x.deviceId().equals(d1p0.deviceId())) |
180 | .findFirst() | 199 | .findFirst() |
181 | .get(); | 200 | .get(); |
182 | - assertThat(rule1.deviceId(), is(d1p0.deviceId())); | 201 | + verifyIdAndPriority(rule1, d1p0.deviceId()); |
183 | assertThat(rule1.selector(), | 202 | assertThat(rule1.selector(), |
184 | is(DefaultTrafficSelector.builder(selector).matchInPort(d1p0.port()).build())); | 203 | is(DefaultTrafficSelector.builder(selector).matchInPort(d1p0.port()).build())); |
185 | assertThat(rule1.treatment(), | 204 | assertThat(rule1.treatment(), |
186 | is(DefaultTrafficTreatment.builder().setOutput(d1p1.port()).build())); | 205 | is(DefaultTrafficTreatment.builder().setOutput(d1p1.port()).build())); |
187 | - assertThat(rule1.priority(), is(intent.priority())); | 206 | + |
188 | 207 | ||
189 | FlowRule rule2 = rules.stream() | 208 | FlowRule rule2 = rules.stream() |
190 | .filter(x -> x.deviceId().equals(d2p0.deviceId())) | 209 | .filter(x -> x.deviceId().equals(d2p0.deviceId())) |
191 | .findFirst() | 210 | .findFirst() |
192 | .get(); | 211 | .get(); |
193 | - assertThat(rule2.deviceId(), is(d2p0.deviceId())); | 212 | + verifyIdAndPriority(rule2, d2p0.deviceId()); |
194 | assertThat(rule2.selector(), | 213 | assertThat(rule2.selector(), |
195 | is(DefaultTrafficSelector.builder(selector).matchInPort(d2p0.port()).build())); | 214 | is(DefaultTrafficSelector.builder(selector).matchInPort(d2p0.port()).build())); |
196 | assertThat(rule2.treatment(), | 215 | assertThat(rule2.treatment(), |
197 | is(DefaultTrafficTreatment.builder().setOutput(d2p1.port()).build())); | 216 | is(DefaultTrafficTreatment.builder().setOutput(d2p1.port()).build())); |
198 | - assertThat(rule2.priority(), is(intent.priority())); | ||
199 | 217 | ||
200 | FlowRule rule3 = rules.stream() | 218 | FlowRule rule3 = rules.stream() |
201 | .filter(x -> x.deviceId().equals(d3p0.deviceId())) | 219 | .filter(x -> x.deviceId().equals(d3p0.deviceId())) |
202 | .findFirst() | 220 | .findFirst() |
203 | .get(); | 221 | .get(); |
204 | - assertThat(rule3.deviceId(), is(d3p1.deviceId())); | 222 | + verifyIdAndPriority(rule3, d3p1.deviceId()); |
205 | assertThat(rule3.selector(), | 223 | assertThat(rule3.selector(), |
206 | is(DefaultTrafficSelector.builder(selector).matchInPort(d3p1.port()).build())); | 224 | is(DefaultTrafficSelector.builder(selector).matchInPort(d3p1.port()).build())); |
207 | assertThat(rule3.treatment(), | 225 | assertThat(rule3.treatment(), |
208 | is(DefaultTrafficTreatment.builder(treatment).setOutput(d3p0.port()).build())); | 226 | is(DefaultTrafficTreatment.builder(treatment).setOutput(d3p0.port()).build())); |
209 | - assertThat(rule3.priority(), is(intent.priority())); | ||
210 | 227 | ||
211 | sut.deactivate(); | 228 | sut.deactivate(); |
212 | } | 229 | } |
... | @@ -216,10 +233,10 @@ public class PathIntentCompilerTest { | ... | @@ -216,10 +233,10 @@ public class PathIntentCompilerTest { |
216 | * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}. | 233 | * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}. |
217 | */ | 234 | */ |
218 | @Test | 235 | @Test |
219 | - public void testEncapCompile() { | 236 | + public void testVlanEncapCompile() { |
220 | sut.activate(); | 237 | sut.activate(); |
221 | 238 | ||
222 | - List<Intent> compiled = sut.compile(constraintIntent, Collections.emptyList(), Collections.emptySet()); | 239 | + List<Intent> compiled = sut.compile(constraintVlanIntent, Collections.emptyList(), Collections.emptySet()); |
223 | assertThat(compiled, hasSize(1)); | 240 | assertThat(compiled, hasSize(1)); |
224 | 241 | ||
225 | Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules(); | 242 | Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules(); |
... | @@ -229,28 +246,26 @@ public class PathIntentCompilerTest { | ... | @@ -229,28 +246,26 @@ public class PathIntentCompilerTest { |
229 | .filter(x -> x.deviceId().equals(d1p0.deviceId())) | 246 | .filter(x -> x.deviceId().equals(d1p0.deviceId())) |
230 | .findFirst() | 247 | .findFirst() |
231 | .get(); | 248 | .get(); |
232 | - assertThat(rule1.deviceId(), is(d1p0.deviceId())); | 249 | + verifyIdAndPriority(rule1, d1p0.deviceId()); |
233 | - assertThat(rule1.priority(), is(intent.priority())); | 250 | + assertThat(rule1.selector(), is(DefaultTrafficSelector.builder(selector) |
234 | - verifyEncapSelector(rule1.selector(), d1p0, VlanId.NONE); | 251 | + .matchInPort(d1p0.port()).build())); |
235 | - VlanId vlanToEncap = verifyEncapTreatment(rule1.treatment(), d1p1, true, false); | 252 | + VlanId vlanToEncap = verifyVlanEncapTreatment(rule1.treatment(), d1p1, true, false); |
236 | 253 | ||
237 | FlowRule rule2 = rules.stream() | 254 | FlowRule rule2 = rules.stream() |
238 | .filter(x -> x.deviceId().equals(d2p0.deviceId())) | 255 | .filter(x -> x.deviceId().equals(d2p0.deviceId())) |
239 | .findFirst() | 256 | .findFirst() |
240 | .get(); | 257 | .get(); |
241 | - assertThat(rule2.deviceId(), is(d2p0.deviceId())); | 258 | + verifyIdAndPriority(rule2, d2p0.deviceId()); |
242 | - assertThat(rule2.priority(), is(intent.priority())); | 259 | + verifyVlanEncapSelector(rule2.selector(), d2p0, vlanToEncap); |
243 | - verifyEncapSelector(rule2.selector(), d2p0, vlanToEncap); | 260 | + verifyVlanEncapTreatment(rule2.treatment(), d2p1, false, false); |
244 | - verifyEncapTreatment(rule2.treatment(), d2p1, false, false); | ||
245 | 261 | ||
246 | FlowRule rule3 = rules.stream() | 262 | FlowRule rule3 = rules.stream() |
247 | .filter(x -> x.deviceId().equals(d3p0.deviceId())) | 263 | .filter(x -> x.deviceId().equals(d3p0.deviceId())) |
248 | .findFirst() | 264 | .findFirst() |
249 | .get(); | 265 | .get(); |
250 | - assertThat(rule3.deviceId(), is(d3p1.deviceId())); | 266 | + verifyIdAndPriority(rule3, d3p1.deviceId()); |
251 | - assertThat(rule3.priority(), is(intent.priority())); | 267 | + verifyVlanEncapSelector(rule3.selector(), d3p1, vlanToEncap); |
252 | - verifyEncapSelector(rule3.selector(), d3p1, vlanToEncap); | 268 | + verifyVlanEncapTreatment(rule3.treatment(), d3p0, false, true); |
253 | - verifyEncapTreatment(rule3.treatment(), d3p0, false, true); | ||
254 | 269 | ||
255 | sut.deactivate(); | 270 | sut.deactivate(); |
256 | } | 271 | } |
... | @@ -275,27 +290,24 @@ public class PathIntentCompilerTest { | ... | @@ -275,27 +290,24 @@ public class PathIntentCompilerTest { |
275 | .filter(x -> x.deviceId().equals(d1p0.deviceId())) | 290 | .filter(x -> x.deviceId().equals(d1p0.deviceId())) |
276 | .findFirst() | 291 | .findFirst() |
277 | .get(); | 292 | .get(); |
278 | - assertThat(rule1.deviceId(), is(d1p0.deviceId())); | 293 | + verifyIdAndPriority(rule1, d1p0.deviceId()); |
279 | - assertThat(rule1.priority(), is(intent.priority())); | 294 | + verifyVlanEncapSelector(rule1.selector(), d1p0, ingressVlan); |
280 | - verifyEncapSelector(rule1.selector(), d1p0, ingressVlan); | 295 | + VlanId vlanToEncap = verifyVlanEncapTreatment(rule1.treatment(), d1p1, true, false); |
281 | - VlanId vlanToEncap = verifyEncapTreatment(rule1.treatment(), d1p1, true, false); | ||
282 | 296 | ||
283 | FlowRule rule2 = rules.stream() | 297 | FlowRule rule2 = rules.stream() |
284 | .filter(x -> x.deviceId().equals(d2p0.deviceId())) | 298 | .filter(x -> x.deviceId().equals(d2p0.deviceId())) |
285 | .findFirst() | 299 | .findFirst() |
286 | .get(); | 300 | .get(); |
287 | - assertThat(rule2.deviceId(), is(d2p0.deviceId())); | 301 | + verifyIdAndPriority(rule2, d2p0.deviceId()); |
288 | - assertThat(rule2.priority(), is(intent.priority())); | 302 | + verifyVlanEncapSelector(rule2.selector(), d2p0, vlanToEncap); |
289 | - verifyEncapSelector(rule2.selector(), d2p0, vlanToEncap); | 303 | + verifyVlanEncapTreatment(rule2.treatment(), d2p1, false, false); |
290 | - verifyEncapTreatment(rule2.treatment(), d2p1, false, false); | ||
291 | 304 | ||
292 | FlowRule rule3 = rules.stream() | 305 | FlowRule rule3 = rules.stream() |
293 | .filter(x -> x.deviceId().equals(d3p0.deviceId())) | 306 | .filter(x -> x.deviceId().equals(d3p0.deviceId())) |
294 | .findFirst() | 307 | .findFirst() |
295 | .get(); | 308 | .get(); |
296 | - assertThat(rule3.deviceId(), is(d3p1.deviceId())); | 309 | + verifyIdAndPriority(rule3, d3p1.deviceId()); |
297 | - assertThat(rule3.priority(), is(intent.priority())); | 310 | + verifyVlanEncapSelector(rule3.selector(), d3p1, vlanToEncap); |
298 | - verifyEncapSelector(rule3.selector(), d3p1, vlanToEncap); | ||
299 | Set<L2ModificationInstruction.ModVlanIdInstruction> vlanMod = rule3.treatment().allInstructions().stream() | 311 | Set<L2ModificationInstruction.ModVlanIdInstruction> vlanMod = rule3.treatment().allInstructions().stream() |
300 | .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction) | 312 | .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction) |
301 | .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x) | 313 | .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x) |
... | @@ -311,7 +323,7 @@ public class PathIntentCompilerTest { | ... | @@ -311,7 +323,7 @@ public class PathIntentCompilerTest { |
311 | sut.deactivate(); | 323 | sut.deactivate(); |
312 | } | 324 | } |
313 | 325 | ||
314 | - private VlanId verifyEncapTreatment(TrafficTreatment trafficTreatment, | 326 | + private VlanId verifyVlanEncapTreatment(TrafficTreatment trafficTreatment, |
315 | ConnectPoint egress, boolean isIngress, boolean isEgress) { | 327 | ConnectPoint egress, boolean isIngress, boolean isEgress) { |
316 | Set<Instructions.OutputInstruction> ruleOutput = trafficTreatment.allInstructions().stream() | 328 | Set<Instructions.OutputInstruction> ruleOutput = trafficTreatment.allInstructions().stream() |
317 | .filter(treat -> treat instanceof Instructions.OutputInstruction) | 329 | .filter(treat -> treat instanceof Instructions.OutputInstruction) |
... | @@ -347,9 +359,101 @@ public class PathIntentCompilerTest { | ... | @@ -347,9 +359,101 @@ public class PathIntentCompilerTest { |
347 | 359 | ||
348 | } | 360 | } |
349 | 361 | ||
350 | - private void verifyEncapSelector(TrafficSelector trafficSelector, ConnectPoint ingress, VlanId vlanToMatch) { | 362 | + private void verifyVlanEncapSelector(TrafficSelector trafficSelector, ConnectPoint ingress, VlanId vlanToMatch) { |
363 | + | ||
364 | + assertThat(trafficSelector, is(DefaultTrafficSelector.builder().matchInPort(ingress.port()) | ||
365 | + .matchVlanId(vlanToMatch).build())); | ||
366 | + } | ||
367 | + | ||
368 | + /** | ||
369 | + * Tests the compilation behavior of the path intent compiler in case of | ||
370 | + * encasulation costraint {@link EncapsulationConstraint}. | ||
371 | + */ | ||
372 | + @Test | ||
373 | + public void testMplsEncapCompile() { | ||
374 | + sut.activate(); | ||
375 | + | ||
376 | + List<Intent> compiled = sut.compile(constraintMplsIntent, Collections.emptyList(), Collections.emptySet()); | ||
377 | + assertThat(compiled, hasSize(1)); | ||
378 | + | ||
379 | + Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules(); | ||
380 | + assertThat(rules, hasSize(3)); | ||
381 | + | ||
382 | + FlowRule rule1 = rules.stream() | ||
383 | + .filter(x -> x.deviceId().equals(d1p0.deviceId())) | ||
384 | + .findFirst() | ||
385 | + .get(); | ||
386 | + verifyIdAndPriority(rule1, d1p0.deviceId()); | ||
387 | + assertThat(rule1.selector(), is(DefaultTrafficSelector.builder(selector) | ||
388 | + .matchInPort(d1p0.port()).build())); | ||
389 | + MplsLabel mplsLabelToEncap = verifyMplsEncapTreatment(rule1.treatment(), d1p1, true, false); | ||
390 | + | ||
391 | + FlowRule rule2 = rules.stream() | ||
392 | + .filter(x -> x.deviceId().equals(d2p0.deviceId())) | ||
393 | + .findFirst() | ||
394 | + .get(); | ||
395 | + verifyIdAndPriority(rule2, d2p0.deviceId()); | ||
396 | + verifyMplsEncapSelector(rule2.selector(), d2p0, mplsLabelToEncap); | ||
397 | + verifyMplsEncapTreatment(rule2.treatment(), d2p1, false, false); | ||
398 | + | ||
399 | + FlowRule rule3 = rules.stream() | ||
400 | + .filter(x -> x.deviceId().equals(d3p0.deviceId())) | ||
401 | + .findFirst() | ||
402 | + .get(); | ||
403 | + verifyIdAndPriority(rule3, d3p1.deviceId()); | ||
404 | + verifyMplsEncapSelector(rule3.selector(), d3p1, mplsLabelToEncap); | ||
405 | + verifyMplsEncapTreatment(rule3.treatment(), d3p0, false, true); | ||
406 | + | ||
407 | + sut.deactivate(); | ||
408 | + } | ||
409 | + | ||
410 | + | ||
411 | + private MplsLabel verifyMplsEncapTreatment(TrafficTreatment trafficTreatment, | ||
412 | + ConnectPoint egress, boolean isIngress, boolean isEgress) { | ||
413 | + Set<Instructions.OutputInstruction> ruleOutput = trafficTreatment.allInstructions().stream() | ||
414 | + .filter(treat -> treat instanceof Instructions.OutputInstruction) | ||
415 | + .map(treat -> (Instructions.OutputInstruction) treat) | ||
416 | + .collect(Collectors.toSet()); | ||
417 | + assertThat(ruleOutput, hasSize(1)); | ||
418 | + assertThat((ruleOutput.iterator().next()).port(), is(egress.port())); | ||
419 | + MplsLabel mplsToEncap = MplsLabel.mplsLabel(0); | ||
420 | + if (isIngress && !isEgress) { | ||
421 | + Set<L2ModificationInstruction.ModMplsLabelInstruction> mplsRules = | ||
422 | + trafficTreatment.allInstructions().stream() | ||
423 | + .filter(treat -> treat instanceof L2ModificationInstruction.ModMplsLabelInstruction) | ||
424 | + .map(x -> (L2ModificationInstruction.ModMplsLabelInstruction) x) | ||
425 | + .collect(Collectors.toSet()); | ||
426 | + assertThat(mplsRules, hasSize(1)); | ||
427 | + L2ModificationInstruction.ModMplsLabelInstruction mplsRule = mplsRules.iterator().next(); | ||
428 | + assertThat(mplsRule.mplsLabel().toInt(), greaterThan(0)); | ||
429 | + mplsToEncap = mplsRule.mplsLabel(); | ||
430 | + } else if (!isIngress && !isEgress) { | ||
431 | + assertThat(trafficTreatment.allInstructions().stream() | ||
432 | + .filter(treat -> treat instanceof L2ModificationInstruction.ModMplsLabelInstruction) | ||
433 | + .collect(Collectors.toSet()), hasSize(0)); | ||
434 | + } else { | ||
435 | + assertThat(trafficTreatment.allInstructions().stream() | ||
436 | + .filter(treat -> treat instanceof L2ModificationInstruction.ModMplsLabelInstruction) | ||
437 | + .collect(Collectors.toSet()), hasSize(0)); | ||
438 | + assertThat(trafficTreatment.allInstructions().stream() | ||
439 | + .filter(treat -> treat instanceof L2ModificationInstruction.PushHeaderInstructions) | ||
440 | + .collect(Collectors.toSet()), hasSize(1)); | ||
441 | + | ||
442 | + } | ||
443 | + | ||
444 | + return mplsToEncap; | ||
445 | + | ||
446 | + } | ||
447 | + | ||
448 | + private void verifyMplsEncapSelector(TrafficSelector trafficSelector, ConnectPoint ingress, MplsLabel mplsLabel) { | ||
449 | + | ||
450 | + assertThat(trafficSelector, is(DefaultTrafficSelector.builder() | ||
451 | + .matchInPort(ingress.port()).matchEthType(Ethernet.MPLS_UNICAST) | ||
452 | + .matchMplsLabel(mplsLabel).build())); | ||
453 | + } | ||
351 | 454 | ||
352 | - is(DefaultTrafficSelector.builder(selector).matchInPort(ingress.port()) | 455 | + private void verifyIdAndPriority(FlowRule rule, DeviceId deviceId) { |
353 | - .matchVlanId(vlanToMatch).build()); | 456 | + assertThat(rule.deviceId(), is(deviceId)); |
457 | + assertThat(rule.priority(), is(PRIORITY)); | ||
354 | } | 458 | } |
355 | } | 459 | } | ... | ... |
-
Please register or login to post a comment