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