Committed by
Gerrit Code Review
fix egress packet treatment ONOS-3467
Change-Id: Ia88568d0ed8f1a982479e5212495923d55238d7b
Showing
2 changed files
with
88 additions
and
2 deletions
| ... | @@ -38,6 +38,7 @@ import org.onosproject.net.flow.TrafficSelector; | ... | @@ -38,6 +38,7 @@ import org.onosproject.net.flow.TrafficSelector; |
| 38 | import org.onosproject.net.flow.TrafficTreatment; | 38 | import org.onosproject.net.flow.TrafficTreatment; |
| 39 | import org.onosproject.net.flow.criteria.Criterion; | 39 | import org.onosproject.net.flow.criteria.Criterion; |
| 40 | import org.onosproject.net.flow.criteria.VlanIdCriterion; | 40 | import org.onosproject.net.flow.criteria.VlanIdCriterion; |
| 41 | +import org.onosproject.net.flow.instructions.L2ModificationInstruction; | ||
| 41 | import org.onosproject.net.intent.FlowRuleIntent; | 42 | import org.onosproject.net.intent.FlowRuleIntent; |
| 42 | import org.onosproject.net.intent.Intent; | 43 | import org.onosproject.net.intent.Intent; |
| 43 | import org.onosproject.net.intent.IntentCompiler; | 44 | import org.onosproject.net.intent.IntentCompiler; |
| ... | @@ -221,16 +222,28 @@ public class PathIntentCompiler implements IntentCompiler<PathIntent> { | ... | @@ -221,16 +222,28 @@ public class PathIntentCompiler implements IntentCompiler<PathIntent> { |
| 221 | .matchInPort(prev.port()) | 222 | .matchInPort(prev.port()) |
| 222 | .matchVlanId(prevVlanId).build(); | 223 | .matchVlanId(prevVlanId).build(); |
| 223 | TrafficTreatment.Builder egressTreat = DefaultTrafficTreatment.builder(intent.treatment()); | 224 | TrafficTreatment.Builder egressTreat = DefaultTrafficTreatment.builder(intent.treatment()); |
| 225 | + | ||
| 226 | + Optional<L2ModificationInstruction.ModVlanIdInstruction> modVlanIdInstruction = intent.treatment() | ||
| 227 | + .allInstructions().stream().filter( | ||
| 228 | + instruction -> instruction instanceof L2ModificationInstruction.ModVlanIdInstruction) | ||
| 229 | + .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x).findAny(); | ||
| 230 | + | ||
| 231 | + Optional<L2ModificationInstruction.PopVlanInstruction> popVlanInstruction = intent.treatment() | ||
| 232 | + .allInstructions().stream().filter( | ||
| 233 | + instruction -> instruction instanceof L2ModificationInstruction.PopVlanInstruction) | ||
| 234 | + .map(x -> (L2ModificationInstruction.PopVlanInstruction) x).findAny(); | ||
| 235 | + | ||
| 236 | + if (!modVlanIdInstruction.isPresent() && !popVlanInstruction.isPresent()) { | ||
| 224 | if (vlanCriterion.isPresent()) { | 237 | if (vlanCriterion.isPresent()) { |
| 225 | egressTreat.setVlanId(vlanCriterion.get().vlanId()); | 238 | egressTreat.setVlanId(vlanCriterion.get().vlanId()); |
| 226 | } else { | 239 | } else { |
| 227 | egressTreat.popVlan(); | 240 | egressTreat.popVlan(); |
| 228 | } | 241 | } |
| 242 | + } | ||
| 229 | 243 | ||
| 230 | rules.add(createFlowRule(egressSelector, | 244 | rules.add(createFlowRule(egressSelector, |
| 231 | egressTreat.build(), prev, link.src(), intent.priority(), true)); | 245 | egressTreat.build(), prev, link.src(), intent.priority(), true)); |
| 232 | } | 246 | } |
| 233 | - | ||
| 234 | } | 247 | } |
| 235 | return rules; | 248 | return rules; |
| 236 | 249 | ... | ... |
| ... | @@ -72,6 +72,13 @@ public class PathIntentCompilerTest { | ... | @@ -72,6 +72,13 @@ public class PathIntentCompilerTest { |
| 72 | 72 | ||
| 73 | private final TrafficSelector selector = DefaultTrafficSelector.builder().build(); | 73 | private final TrafficSelector selector = DefaultTrafficSelector.builder().build(); |
| 74 | private final TrafficTreatment treatment = DefaultTrafficTreatment.builder().build(); | 74 | private final TrafficTreatment treatment = DefaultTrafficTreatment.builder().build(); |
| 75 | + private final VlanId ingressVlan = VlanId.vlanId(((short) 101)); | ||
| 76 | + private final TrafficSelector vlanSelector = DefaultTrafficSelector.builder() | ||
| 77 | + .matchVlanId(ingressVlan).build(); | ||
| 78 | + private final VlanId egressVlan = VlanId.vlanId((short) 100); | ||
| 79 | + private final TrafficTreatment vlanTreatment = DefaultTrafficTreatment.builder() | ||
| 80 | + .setVlanId(egressVlan).build(); | ||
| 81 | + | ||
| 75 | private final ApplicationId appId = new TestApplicationId("test"); | 82 | private final ApplicationId appId = new TestApplicationId("test"); |
| 76 | private final ProviderId pid = new ProviderId("of", "test"); | 83 | private final ProviderId pid = new ProviderId("of", "test"); |
| 77 | private final ConnectPoint d1p1 = connectPoint("s1", 0); | 84 | private final ConnectPoint d1p1 = connectPoint("s1", 0); |
| ... | @@ -91,6 +98,7 @@ public class PathIntentCompilerTest { | ... | @@ -91,6 +98,7 @@ public class PathIntentCompilerTest { |
| 91 | private final int hops = links.size() - 1; | 98 | private final int hops = links.size() - 1; |
| 92 | private PathIntent intent; | 99 | private PathIntent intent; |
| 93 | private PathIntent constraintIntent; | 100 | private PathIntent constraintIntent; |
| 101 | + private PathIntent constrainIngressEgressVlanIntent; | ||
| 94 | 102 | ||
| 95 | /** | 103 | /** |
| 96 | * Configures objects used in all the test cases. | 104 | * Configures objects used in all the test cases. |
| ... | @@ -113,6 +121,7 @@ public class PathIntentCompilerTest { | ... | @@ -113,6 +121,7 @@ public class PathIntentCompilerTest { |
| 113 | .priority(PRIORITY) | 121 | .priority(PRIORITY) |
| 114 | .path(new DefaultPath(pid, links, hops)) | 122 | .path(new DefaultPath(pid, links, hops)) |
| 115 | .build(); | 123 | .build(); |
| 124 | + //Intent with VLAN encap without egress VLAN | ||
| 116 | constraintIntent = PathIntent.builder() | 125 | constraintIntent = PathIntent.builder() |
| 117 | .appId(APP_ID) | 126 | .appId(APP_ID) |
| 118 | .selector(selector) | 127 | .selector(selector) |
| ... | @@ -121,6 +130,15 @@ public class PathIntentCompilerTest { | ... | @@ -121,6 +130,15 @@ public class PathIntentCompilerTest { |
| 121 | .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN))) | 130 | .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN))) |
| 122 | .path(new DefaultPath(pid, links, hops)) | 131 | .path(new DefaultPath(pid, links, hops)) |
| 123 | .build(); | 132 | .build(); |
| 133 | + //Intent with VLAN encap with ingress and egress VLAN | ||
| 134 | + constrainIngressEgressVlanIntent = PathIntent.builder() | ||
| 135 | + .appId(APP_ID) | ||
| 136 | + .selector(vlanSelector) | ||
| 137 | + .treatment(vlanTreatment) | ||
| 138 | + .priority(PRIORITY) | ||
| 139 | + .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN))) | ||
| 140 | + .path(new DefaultPath(pid, links, hops)) | ||
| 141 | + .build(); | ||
| 124 | intentExtensionService = createMock(IntentExtensionService.class); | 142 | intentExtensionService = createMock(IntentExtensionService.class); |
| 125 | intentExtensionService.registerCompiler(PathIntent.class, sut); | 143 | intentExtensionService.registerCompiler(PathIntent.class, sut); |
| 126 | intentExtensionService.unregisterCompiler(PathIntent.class); | 144 | intentExtensionService.unregisterCompiler(PathIntent.class); |
| ... | @@ -187,7 +205,7 @@ public class PathIntentCompilerTest { | ... | @@ -187,7 +205,7 @@ public class PathIntentCompilerTest { |
| 187 | 205 | ||
| 188 | /** | 206 | /** |
| 189 | * Tests the compilation behavior of the path intent compiler in case of | 207 | * Tests the compilation behavior of the path intent compiler in case of |
| 190 | - * encasulation costraint {@link EncapsulationConstraint}. | 208 | + * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}. |
| 191 | */ | 209 | */ |
| 192 | @Test | 210 | @Test |
| 193 | public void testEncapCompile() { | 211 | public void testEncapCompile() { |
| ... | @@ -229,6 +247,61 @@ public class PathIntentCompilerTest { | ... | @@ -229,6 +247,61 @@ public class PathIntentCompilerTest { |
| 229 | sut.deactivate(); | 247 | sut.deactivate(); |
| 230 | } | 248 | } |
| 231 | 249 | ||
| 250 | + /** | ||
| 251 | + * Tests the compilation behavior of the path intent compiler in case of | ||
| 252 | + * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}. | ||
| 253 | + * This test includes a selector to match a VLAN at the ingress and a treatment to set VLAN at the egress. | ||
| 254 | + */ | ||
| 255 | + @Test | ||
| 256 | + public void testEncapIngressEgressVlansCompile() { | ||
| 257 | + sut.activate(); | ||
| 258 | + | ||
| 259 | + List<Intent> compiled = sut.compile(constrainIngressEgressVlanIntent, | ||
| 260 | + Collections.emptyList(), Collections.emptySet()); | ||
| 261 | + assertThat(compiled, hasSize(1)); | ||
| 262 | + | ||
| 263 | + Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules(); | ||
| 264 | + assertThat(rules, hasSize(3)); | ||
| 265 | + | ||
| 266 | + FlowRule rule1 = rules.stream() | ||
| 267 | + .filter(x -> x.deviceId().equals(d1p0.deviceId())) | ||
| 268 | + .findFirst() | ||
| 269 | + .get(); | ||
| 270 | + assertThat(rule1.deviceId(), is(d1p0.deviceId())); | ||
| 271 | + assertThat(rule1.priority(), is(intent.priority())); | ||
| 272 | + verifyEncapSelector(rule1.selector(), d1p0, ingressVlan); | ||
| 273 | + VlanId vlanToEncap = verifyEncapTreatment(rule1.treatment(), d1p1, true, false); | ||
| 274 | + | ||
| 275 | + FlowRule rule2 = rules.stream() | ||
| 276 | + .filter(x -> x.deviceId().equals(d2p0.deviceId())) | ||
| 277 | + .findFirst() | ||
| 278 | + .get(); | ||
| 279 | + assertThat(rule2.deviceId(), is(d2p0.deviceId())); | ||
| 280 | + assertThat(rule2.priority(), is(intent.priority())); | ||
| 281 | + verifyEncapSelector(rule2.selector(), d2p0, vlanToEncap); | ||
| 282 | + verifyEncapTreatment(rule2.treatment(), d2p1, false, false); | ||
| 283 | + | ||
| 284 | + FlowRule rule3 = rules.stream() | ||
| 285 | + .filter(x -> x.deviceId().equals(d3p0.deviceId())) | ||
| 286 | + .findFirst() | ||
| 287 | + .get(); | ||
| 288 | + assertThat(rule3.deviceId(), is(d3p1.deviceId())); | ||
| 289 | + assertThat(rule3.priority(), is(intent.priority())); | ||
| 290 | + verifyEncapSelector(rule3.selector(), d3p1, vlanToEncap); | ||
| 291 | + Set<L2ModificationInstruction.ModVlanIdInstruction> vlanMod = rule3.treatment().allInstructions().stream() | ||
| 292 | + .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction) | ||
| 293 | + .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x) | ||
| 294 | + .collect(Collectors.toSet()); | ||
| 295 | + assertThat(rule3.treatment().allInstructions().stream() | ||
| 296 | + .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction) | ||
| 297 | + .collect(Collectors.toSet()), hasSize(1)); | ||
| 298 | + assertThat(vlanMod.iterator().next().vlanId(), is(egressVlan)); | ||
| 299 | + assertThat(rule3.treatment().allInstructions().stream() | ||
| 300 | + .filter(treat -> treat instanceof L2ModificationInstruction.PopVlanInstruction) | ||
| 301 | + .collect(Collectors.toSet()), hasSize(0)); | ||
| 302 | + | ||
| 303 | + sut.deactivate(); | ||
| 304 | + } | ||
| 232 | 305 | ||
| 233 | private VlanId verifyEncapTreatment(TrafficTreatment trafficTreatment, | 306 | private VlanId verifyEncapTreatment(TrafficTreatment trafficTreatment, |
| 234 | ConnectPoint egress, boolean isIngress, boolean isEgress) { | 307 | ConnectPoint egress, boolean isIngress, boolean isEgress) { | ... | ... |
-
Please register or login to post a comment