diff options
author | Ashlee Young <ashlee@wildernessvoice.com> | 2015-12-01 05:49:27 -0800 |
---|---|---|
committer | Ashlee Young <ashlee@wildernessvoice.com> | 2015-12-01 05:49:27 -0800 |
commit | e63291850fd0795c5700e25e67e5dee89ba54c5f (patch) | |
tree | 9707289536ad95bb739c9856761ad43275e07d8c /framework/src/onos/apps/olt | |
parent | 671823e12bc13be9a8b87a5d7de33da1bb7a44e8 (diff) |
onos commit hash c2999f30c69e50df905a9d175ef80b3f23a98514
Change-Id: I2bb8562c4942b6d6a6d60b663db2e17540477b81
Signed-off-by: Ashlee Young <ashlee@wildernessvoice.com>
Diffstat (limited to 'framework/src/onos/apps/olt')
-rw-r--r-- | framework/src/onos/apps/olt/src/main/java/org/onosproject/olt/Olt.java | 359 |
1 files changed, 359 insertions, 0 deletions
diff --git a/framework/src/onos/apps/olt/src/main/java/org/onosproject/olt/Olt.java b/framework/src/onos/apps/olt/src/main/java/org/onosproject/olt/Olt.java new file mode 100644 index 00000000..ffc4705a --- /dev/null +++ b/framework/src/onos/apps/olt/src/main/java/org/onosproject/olt/Olt.java @@ -0,0 +1,359 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.olt; + +import com.google.common.base.Strings; +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Modified; +import org.apache.felix.scr.annotations.Property; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.apache.felix.scr.annotations.Service; +import org.onlab.packet.VlanId; +import org.onlab.util.Tools; +import org.onosproject.core.ApplicationId; +import org.onosproject.core.CoreService; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.DeviceId; +import org.onosproject.net.Port; +import org.onosproject.net.PortNumber; +import org.onosproject.net.config.ConfigFactory; +import org.onosproject.net.config.NetworkConfigEvent; +import org.onosproject.net.config.NetworkConfigListener; +import org.onosproject.net.config.NetworkConfigRegistry; +import org.onosproject.net.config.basics.SubjectFactories; +import org.onosproject.net.device.DeviceEvent; +import org.onosproject.net.device.DeviceListener; +import org.onosproject.net.device.DeviceService; +import org.onosproject.net.flow.DefaultTrafficSelector; +import org.onosproject.net.flow.DefaultTrafficTreatment; +import org.onosproject.net.flow.TrafficSelector; +import org.onosproject.net.flow.TrafficTreatment; +import org.onosproject.net.flowobjective.DefaultForwardingObjective; +import org.onosproject.net.flowobjective.FlowObjectiveService; +import org.onosproject.net.flowobjective.ForwardingObjective; +import org.osgi.service.component.ComponentContext; +import org.slf4j.Logger; + +import java.util.Dictionary; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; + +import static org.slf4j.LoggerFactory.getLogger; + +/** + * Provisions rules on access devices. + */ +@Service +@Component(immediate = true) +public class Olt implements AccessDeviceService { + private final Logger log = getLogger(getClass()); + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected FlowObjectiveService flowObjectiveService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected DeviceService deviceService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected CoreService coreService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected NetworkConfigRegistry networkConfig; + + private final DeviceListener deviceListener = new InternalDeviceListener(); + + private ApplicationId appId; + + private static final VlanId DEFAULT_VLAN = VlanId.vlanId((short) 0); + public static final int OFFSET = 200; + + public static final int UPLINK_PORT = 129; + public static final int GFAST_UPLINK_PORT = 100; + + public static final String OLT_DEVICE = "of:90e2ba82f97791e9"; + public static final String GFAST_DEVICE = "of:0011223344551357"; + + @Property(name = "uplinkPort", intValue = UPLINK_PORT, + label = "The OLT's uplink port number") + private int uplinkPort = UPLINK_PORT; + + @Property(name = "gfastUplink", intValue = GFAST_UPLINK_PORT, + label = "The OLT's uplink port number") + private int gfastUplink = GFAST_UPLINK_PORT; + + //TODO: replace this with an annotation lookup + @Property(name = "oltDevice", value = OLT_DEVICE, + label = "The OLT device id") + private String oltDevice = OLT_DEVICE; + + @Property(name = "gfastDevice", value = GFAST_DEVICE, + label = "The gfast device id") + private String gfastDevice = GFAST_DEVICE; + + private Map<DeviceId, AccessDeviceData> oltData = new ConcurrentHashMap<>(); + + private InternalNetworkConfigListener configListener = + new InternalNetworkConfigListener(); + private static final Class<AccessDeviceConfig> CONFIG_CLASS = + AccessDeviceConfig.class; + + private ConfigFactory<DeviceId, AccessDeviceConfig> configFactory = + new ConfigFactory<DeviceId, AccessDeviceConfig>( + SubjectFactories.DEVICE_SUBJECT_FACTORY, CONFIG_CLASS, "accessDevice") { + @Override + public AccessDeviceConfig createConfig() { + return new AccessDeviceConfig(); + } + }; + + @Activate + public void activate() { + appId = coreService.registerApplication("org.onosproject.olt"); + + networkConfig.registerConfigFactory(configFactory); + networkConfig.addListener(configListener); + + networkConfig.getSubjects(DeviceId.class, AccessDeviceConfig.class).forEach( + subject -> { + AccessDeviceConfig config = networkConfig.getConfig(subject, AccessDeviceConfig.class); + if (config != null) { + AccessDeviceData data = config.getOlt(); + oltData.put(data.deviceId(), data); + } + } + ); + + /*deviceService.addListener(deviceListener); + + deviceService.getPorts(DeviceId.deviceId(oltDevice)).stream().forEach( + port -> { + if (!port.number().isLogical() && port.isEnabled()) { + short vlanId = fetchVlanId(port.number()); + if (vlanId > 0) { + provisionVlanOnPort(oltDevice, uplinkPort, port.number(), (short) 7); + provisionVlanOnPort(oltDevice, uplinkPort, port.number(), vlanId); + } + } + } + );*/ + + + deviceService.getPorts(DeviceId.deviceId(gfastDevice)).stream() + .filter(port -> !port.number().isLogical()) + .filter(Port::isEnabled) + .forEach(port -> { + short vlanId = (short) (fetchVlanId(port.number()) + OFFSET); + if (vlanId > 0) { + provisionVlanOnPort(gfastDevice, gfastUplink, port.number(), vlanId); + } + } + ); + log.info("Started with Application ID {}", appId.id()); + } + + @Deactivate + public void deactivate() { + networkConfig.removeListener(configListener); + networkConfig.unregisterConfigFactory(configFactory); + log.info("Stopped"); + } + + @Modified + public void modified(ComponentContext context) { + Dictionary<?, ?> properties = context.getProperties(); + + String s = Tools.get(properties, "uplinkPort"); + uplinkPort = Strings.isNullOrEmpty(s) ? UPLINK_PORT : Integer.parseInt(s); + + s = Tools.get(properties, "oltDevice"); + oltDevice = Strings.isNullOrEmpty(s) ? OLT_DEVICE : s; + } + + private short fetchVlanId(PortNumber port) { + long p = port.toLong() + OFFSET; + if (p > 4095) { + log.warn("Port Number {} exceeds vlan max", port); + return -1; + } + return (short) p; + } + + private void provisionVlanOnPort(String deviceId, int uplinkPort, PortNumber p, short vlanId) { + DeviceId did = DeviceId.deviceId(deviceId); + + TrafficSelector upstream = DefaultTrafficSelector.builder() + .matchVlanId(VlanId.vlanId(vlanId)) + .matchInPort(p) + .build(); + + TrafficSelector downStream = DefaultTrafficSelector.builder() + .matchVlanId(VlanId.vlanId(vlanId)) + .matchInPort(PortNumber.portNumber(uplinkPort)) + .build(); + + TrafficTreatment upstreamTreatment = DefaultTrafficTreatment.builder() + .setOutput(PortNumber.portNumber(uplinkPort)) + .build(); + + TrafficTreatment downStreamTreatment = DefaultTrafficTreatment.builder() + .setOutput(p) + .build(); + + + ForwardingObjective upFwd = DefaultForwardingObjective.builder() + .withFlag(ForwardingObjective.Flag.VERSATILE) + .withPriority(1000) + .makePermanent() + .withSelector(upstream) + .fromApp(appId) + .withTreatment(upstreamTreatment) + .add(); + + ForwardingObjective downFwd = DefaultForwardingObjective.builder() + .withFlag(ForwardingObjective.Flag.VERSATILE) + .withPriority(1000) + .makePermanent() + .withSelector(downStream) + .fromApp(appId) + .withTreatment(downStreamTreatment) + .add(); + + flowObjectiveService.forward(did, upFwd); + flowObjectiveService.forward(did, downFwd); + } + + @Override + public void provisionSubscriber(ConnectPoint port, VlanId vlan) { + AccessDeviceData olt = oltData.get(port.deviceId()); + + if (olt == null) { + log.warn("No data found for OLT device {}", port.deviceId()); + return; + } + + provisionVlans(olt.deviceId(), olt.uplink(), port.port(), vlan, olt.vlan(), + olt.defaultVlan()); + } + + private void provisionVlans(DeviceId deviceId, PortNumber uplinkPort, + PortNumber subscriberPort, + VlanId subscriberVlan, VlanId deviceVlan, + Optional<VlanId> defaultVlan) { + + TrafficSelector upstream = DefaultTrafficSelector.builder() + .matchVlanId((defaultVlan.isPresent()) ? defaultVlan.get() : DEFAULT_VLAN) + .matchInPort(subscriberPort) + .build(); + + TrafficSelector downstream = DefaultTrafficSelector.builder() + .matchVlanId(deviceVlan) + .matchInPort(uplinkPort) + .build(); + + TrafficTreatment upstreamTreatment = DefaultTrafficTreatment.builder() + .setVlanId(subscriberVlan) + .pushVlan() + .setVlanId(deviceVlan) + .setOutput(uplinkPort) + .build(); + + TrafficTreatment downstreamTreatment = DefaultTrafficTreatment.builder() + .popVlan() + .setVlanId((defaultVlan.isPresent()) ? defaultVlan.get() : DEFAULT_VLAN) + .setOutput(subscriberPort) + .build(); + + + ForwardingObjective upFwd = DefaultForwardingObjective.builder() + .withFlag(ForwardingObjective.Flag.VERSATILE) + .withPriority(1000) + .makePermanent() + .withSelector(upstream) + .fromApp(appId) + .withTreatment(upstreamTreatment) + .add(); + + ForwardingObjective downFwd = DefaultForwardingObjective.builder() + .withFlag(ForwardingObjective.Flag.VERSATILE) + .withPriority(1000) + .makePermanent() + .withSelector(downstream) + .fromApp(appId) + .withTreatment(downstreamTreatment) + .add(); + + flowObjectiveService.forward(deviceId, upFwd); + flowObjectiveService.forward(deviceId, downFwd); + } + + @Override + public void removeSubscriber(ConnectPoint port) { + throw new UnsupportedOperationException("Not yet implemented"); + } + + private class InternalDeviceListener implements DeviceListener { + @Override + public void event(DeviceEvent event) { + DeviceId devId = DeviceId.deviceId(oltDevice); + switch (event.type()) { + case PORT_ADDED: + case PORT_UPDATED: + if (devId.equals(event.subject().id()) && event.port().isEnabled()) { + short vlanId = fetchVlanId(event.port().number()); + provisionVlanOnPort(gfastDevice, uplinkPort, event.port().number(), vlanId); + } + break; + case DEVICE_ADDED: + case DEVICE_UPDATED: + case DEVICE_REMOVED: + case DEVICE_SUSPENDED: + case DEVICE_AVAILABILITY_CHANGED: + case PORT_REMOVED: + case PORT_STATS_UPDATED: + default: + return; + } + } + } + + private class InternalNetworkConfigListener implements NetworkConfigListener { + @Override + public void event(NetworkConfigEvent event) { + switch (event.type()) { + + case CONFIG_ADDED: + case CONFIG_UPDATED: + if (event.configClass().equals(CONFIG_CLASS)) { + AccessDeviceConfig config = + networkConfig.getConfig((DeviceId) event.subject(), CONFIG_CLASS); + if (config != null) { + oltData.put(config.getOlt().deviceId(), config.getOlt()); + } + } + break; + case CONFIG_UNREGISTERED: + case CONFIG_REMOVED: + default: + break; + } + } + } + +} |