olt installs default rules on startup and when a port shows up
Change-Id: I0db62db020f94500aeae7191f7681745e1268672
Showing
2 changed files
with
87 additions
and
5 deletions
... | @@ -23,12 +23,15 @@ import org.apache.felix.scr.annotations.Deactivate; | ... | @@ -23,12 +23,15 @@ import org.apache.felix.scr.annotations.Deactivate; |
23 | import org.apache.felix.scr.annotations.Reference; | 23 | import org.apache.felix.scr.annotations.Reference; |
24 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 24 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
25 | import org.apache.felix.scr.annotations.Service; | 25 | import org.apache.felix.scr.annotations.Service; |
26 | +import org.onlab.packet.EthType; | ||
27 | +import org.onlab.packet.IPv4; | ||
26 | import org.onlab.packet.VlanId; | 28 | import org.onlab.packet.VlanId; |
27 | import org.onosproject.core.ApplicationId; | 29 | import org.onosproject.core.ApplicationId; |
28 | import org.onosproject.core.CoreService; | 30 | import org.onosproject.core.CoreService; |
29 | import org.onosproject.event.AbstractListenerManager; | 31 | import org.onosproject.event.AbstractListenerManager; |
30 | import org.onosproject.net.ConnectPoint; | 32 | import org.onosproject.net.ConnectPoint; |
31 | import org.onosproject.net.DeviceId; | 33 | import org.onosproject.net.DeviceId; |
34 | +import org.onosproject.net.Port; | ||
32 | import org.onosproject.net.PortNumber; | 35 | import org.onosproject.net.PortNumber; |
33 | import org.onosproject.net.config.ConfigFactory; | 36 | import org.onosproject.net.config.ConfigFactory; |
34 | import org.onosproject.net.config.NetworkConfigEvent; | 37 | import org.onosproject.net.config.NetworkConfigEvent; |
... | @@ -42,7 +45,10 @@ import org.onosproject.net.flow.DefaultTrafficSelector; | ... | @@ -42,7 +45,10 @@ import org.onosproject.net.flow.DefaultTrafficSelector; |
42 | import org.onosproject.net.flow.DefaultTrafficTreatment; | 45 | import org.onosproject.net.flow.DefaultTrafficTreatment; |
43 | import org.onosproject.net.flow.TrafficSelector; | 46 | import org.onosproject.net.flow.TrafficSelector; |
44 | import org.onosproject.net.flow.TrafficTreatment; | 47 | import org.onosproject.net.flow.TrafficTreatment; |
48 | +import org.onosproject.net.flow.criteria.Criteria; | ||
49 | +import org.onosproject.net.flowobjective.DefaultFilteringObjective; | ||
45 | import org.onosproject.net.flowobjective.DefaultForwardingObjective; | 50 | import org.onosproject.net.flowobjective.DefaultForwardingObjective; |
51 | +import org.onosproject.net.flowobjective.FilteringObjective; | ||
46 | import org.onosproject.net.flowobjective.FlowObjectiveService; | 52 | import org.onosproject.net.flowobjective.FlowObjectiveService; |
47 | import org.onosproject.net.flowobjective.ForwardingObjective; | 53 | import org.onosproject.net.flowobjective.ForwardingObjective; |
48 | import org.onosproject.net.flowobjective.Objective; | 54 | import org.onosproject.net.flowobjective.Objective; |
... | @@ -126,6 +132,7 @@ public class Olt | ... | @@ -126,6 +132,7 @@ public class Olt |
126 | networkConfig.registerConfigFactory(configFactory); | 132 | networkConfig.registerConfigFactory(configFactory); |
127 | networkConfig.addListener(configListener); | 133 | networkConfig.addListener(configListener); |
128 | 134 | ||
135 | + | ||
129 | networkConfig.getSubjects(DeviceId.class, AccessDeviceConfig.class).forEach( | 136 | networkConfig.getSubjects(DeviceId.class, AccessDeviceConfig.class).forEach( |
130 | subject -> { | 137 | subject -> { |
131 | AccessDeviceConfig config = networkConfig.getConfig(subject, AccessDeviceConfig.class); | 138 | AccessDeviceConfig config = networkConfig.getConfig(subject, AccessDeviceConfig.class); |
... | @@ -136,6 +143,12 @@ public class Olt | ... | @@ -136,6 +143,12 @@ public class Olt |
136 | } | 143 | } |
137 | ); | 144 | ); |
138 | 145 | ||
146 | + oltData.keySet().stream() | ||
147 | + .flatMap(did -> deviceService.getPorts(did).stream()) | ||
148 | + .filter(p -> oltData.get(p.element().id()).uplink() != p.number()) | ||
149 | + .filter(p -> p.isEnabled()) | ||
150 | + .forEach(p -> installFilteringObjectives((DeviceId) p.element().id(), p)); | ||
151 | + | ||
139 | log.info("Started with Application ID {}", appId.id()); | 152 | log.info("Started with Application ID {}", appId.id()); |
140 | } | 153 | } |
141 | 154 | ||
... | @@ -327,6 +340,57 @@ public class Olt | ... | @@ -327,6 +340,57 @@ public class Olt |
327 | 340 | ||
328 | } | 341 | } |
329 | 342 | ||
343 | + private void installFilteringObjectives(DeviceId devId, Port port) { | ||
344 | + FilteringObjective eapol = DefaultFilteringObjective.builder() | ||
345 | + .permit() | ||
346 | + .withKey(Criteria.matchInPort(port.number())) | ||
347 | + .addCondition(Criteria.matchEthType(EthType.EtherType.EAPOL.ethType())) | ||
348 | + .withMeta(DefaultTrafficTreatment.builder() | ||
349 | + .setOutput(PortNumber.CONTROLLER).build()) | ||
350 | + .fromApp(appId) | ||
351 | + .withPriority(1000) | ||
352 | + .add(new ObjectiveContext() { | ||
353 | + @Override | ||
354 | + public void onSuccess(Objective objective) { | ||
355 | + log.info("Eapol filter for {} on {} installed.", | ||
356 | + devId, port); | ||
357 | + } | ||
358 | + | ||
359 | + @Override | ||
360 | + public void onError(Objective objective, ObjectiveError error) { | ||
361 | + log.info("Eapol filter for {} on {} failed because {}", | ||
362 | + devId, port, error); | ||
363 | + } | ||
364 | + }); | ||
365 | + | ||
366 | + | ||
367 | + FilteringObjective igmp = DefaultFilteringObjective.builder() | ||
368 | + .permit() | ||
369 | + .withKey(Criteria.matchInPort(port.number())) | ||
370 | + .addCondition(Criteria.matchEthType(EthType.EtherType.IPV4.ethType())) | ||
371 | + .addCondition(Criteria.matchIPProtocol(IPv4.PROTOCOL_IGMP)) | ||
372 | + .withMeta(DefaultTrafficTreatment.builder() | ||
373 | + .setOutput(PortNumber.CONTROLLER).build()) | ||
374 | + .fromApp(appId) | ||
375 | + .withPriority(1000) | ||
376 | + .add(new ObjectiveContext() { | ||
377 | + @Override | ||
378 | + public void onSuccess(Objective objective) { | ||
379 | + log.info("Igmp filter for {} on {} installed.", | ||
380 | + devId, port); | ||
381 | + } | ||
382 | + | ||
383 | + @Override | ||
384 | + public void onError(Objective objective, ObjectiveError error) { | ||
385 | + log.info("Igmp filter for {} on {} failed because {}.", | ||
386 | + devId, port, error); | ||
387 | + } | ||
388 | + }); | ||
389 | + | ||
390 | + flowObjectiveService.filter(devId, eapol); | ||
391 | + flowObjectiveService.filter(devId, igmp); | ||
392 | + } | ||
393 | + | ||
330 | private class InternalDeviceListener implements DeviceListener { | 394 | private class InternalDeviceListener implements DeviceListener { |
331 | @Override | 395 | @Override |
332 | public void event(DeviceEvent event) { | 396 | public void event(DeviceEvent event) { |
... | @@ -336,7 +400,20 @@ public class Olt | ... | @@ -336,7 +400,20 @@ public class Olt |
336 | return; | 400 | return; |
337 | } | 401 | } |
338 | switch (event.type()) { | 402 | switch (event.type()) { |
403 | + //TODO: Port handling and bookkeeping should be inproved once | ||
404 | + // olt firmware handles correct behaviour. | ||
339 | case PORT_ADDED: | 405 | case PORT_ADDED: |
406 | + if (event.port().isEnabled()) { | ||
407 | + installFilteringObjectives(devId, event.port()); | ||
408 | + } | ||
409 | + break; | ||
410 | + case PORT_REMOVED: | ||
411 | + AccessDeviceData olt = oltData.get(devId); | ||
412 | + unprovisionSubscriber(devId, olt.uplink(), | ||
413 | + event.port().number(), | ||
414 | + olt.vlan()); | ||
415 | + installFilteringObjectives(devId, event.port()); | ||
416 | + break; | ||
340 | case PORT_UPDATED: | 417 | case PORT_UPDATED: |
341 | break; | 418 | break; |
342 | case DEVICE_ADDED: | 419 | case DEVICE_ADDED: |
... | @@ -352,7 +429,6 @@ public class Olt | ... | @@ -352,7 +429,6 @@ public class Olt |
352 | case DEVICE_UPDATED: | 429 | case DEVICE_UPDATED: |
353 | case DEVICE_SUSPENDED: | 430 | case DEVICE_SUSPENDED: |
354 | case DEVICE_AVAILABILITY_CHANGED: | 431 | case DEVICE_AVAILABILITY_CHANGED: |
355 | - case PORT_REMOVED: | ||
356 | case PORT_STATS_UPDATED: | 432 | case PORT_STATS_UPDATED: |
357 | default: | 433 | default: |
358 | return; | 434 | return; | ... | ... |
... | @@ -120,7 +120,8 @@ public class OltPipeline extends AbstractHandlerBehaviour implements Pipeliner { | ... | @@ -120,7 +120,8 @@ public class OltPipeline extends AbstractHandlerBehaviour implements Pipeliner { |
120 | .limit(1) | 120 | .limit(1) |
121 | .findFirst().get(); | 121 | .findFirst().get(); |
122 | 122 | ||
123 | - if (output != null && !output.port().equals(PortNumber.CONTROLLER)) { | 123 | + if (output == null || !output.port().equals(PortNumber.CONTROLLER)) { |
124 | + log.error("OLT can only filter packet to controller"); | ||
124 | fail(filter, ObjectiveError.UNSUPPORTED); | 125 | fail(filter, ObjectiveError.UNSUPPORTED); |
125 | return; | 126 | return; |
126 | } | 127 | } |
... | @@ -142,15 +143,19 @@ public class OltPipeline extends AbstractHandlerBehaviour implements Pipeliner { | ... | @@ -142,15 +143,19 @@ public class OltPipeline extends AbstractHandlerBehaviour implements Pipeliner { |
142 | return; | 143 | return; |
143 | } | 144 | } |
144 | 145 | ||
145 | - if (ethType.ethType().equals(EthType.EtherType.EAPOL)) { | 146 | + if (ethType.ethType().equals(EthType.EtherType.EAPOL.ethType())) { |
146 | provisionEapol(filter, ethType, output); | 147 | provisionEapol(filter, ethType, output); |
147 | - } else if (ethType.ethType().equals(EthType.EtherType.IPV4)) { | 148 | + } else if (ethType.ethType().equals(EthType.EtherType.IPV4.ethType())) { |
148 | IPProtocolCriterion ipProto = (IPProtocolCriterion) | 149 | IPProtocolCriterion ipProto = (IPProtocolCriterion) |
149 | filterForCriterion(filter.conditions(), Criterion.Type.IP_PROTO); | 150 | filterForCriterion(filter.conditions(), Criterion.Type.IP_PROTO); |
150 | if (ipProto.protocol() == IPv4.PROTOCOL_IGMP) { | 151 | if (ipProto.protocol() == IPv4.PROTOCOL_IGMP) { |
151 | provisionIGMP(filter, ethType, ipProto, output); | 152 | provisionIGMP(filter, ethType, ipProto, output); |
153 | + } else { | ||
154 | + log.error("OLT can only filter igmp"); | ||
155 | + fail(filter, ObjectiveError.UNSUPPORTED); | ||
152 | } | 156 | } |
153 | } else { | 157 | } else { |
158 | + log.error("OLT can only filter eapol and igmp"); | ||
154 | fail(filter, ObjectiveError.UNSUPPORTED); | 159 | fail(filter, ObjectiveError.UNSUPPORTED); |
155 | } | 160 | } |
156 | 161 | ||
... | @@ -389,6 +394,7 @@ public class OltPipeline extends AbstractHandlerBehaviour implements Pipeliner { | ... | @@ -389,6 +394,7 @@ public class OltPipeline extends AbstractHandlerBehaviour implements Pipeliner { |
389 | .makePermanent() | 394 | .makePermanent() |
390 | .withSelector(selector) | 395 | .withSelector(selector) |
391 | .withTreatment(treatment) | 396 | .withTreatment(treatment) |
397 | + .withPriority(filter.priority()) | ||
392 | .build(); | 398 | .build(); |
393 | 399 | ||
394 | FlowRuleOperations.Builder opsBuilder = FlowRuleOperations.builder(); | 400 | FlowRuleOperations.Builder opsBuilder = FlowRuleOperations.builder(); |
... | @@ -446,7 +452,7 @@ public class OltPipeline extends AbstractHandlerBehaviour implements Pipeliner { | ... | @@ -446,7 +452,7 @@ public class OltPipeline extends AbstractHandlerBehaviour implements Pipeliner { |
446 | 452 | ||
447 | private Criterion filterForCriterion(Collection<Criterion> criteria, Criterion.Type type) { | 453 | private Criterion filterForCriterion(Collection<Criterion> criteria, Criterion.Type type) { |
448 | return criteria.stream() | 454 | return criteria.stream() |
449 | - .filter(c -> c.type().equals(Criterion.Type.ETH_TYPE)) | 455 | + .filter(c -> c.type().equals(type)) |
450 | .limit(1) | 456 | .limit(1) |
451 | .findFirst().orElse(null); | 457 | .findFirst().orElse(null); |
452 | } | 458 | } | ... | ... |
-
Please register or login to post a comment