alshabib

olt installs default rules on startup and when a port shows up

Change-Id: I0db62db020f94500aeae7191f7681745e1268672
...@@ -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 }
......