diff options
author | CNlucius <lukai1@huawei.com> | 2016-09-13 11:40:12 +0800 |
---|---|---|
committer | CNlucius <lukai1@huawei.com> | 2016-09-13 11:41:53 +0800 |
commit | b731e2f1dd0972409b136aebc7b463dd72c9cfad (patch) | |
tree | 5107d7d80c19ad8076c2c97c2b5ef8d1cf3ab903 /framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective | |
parent | ee93993458266114c29271a481ef9ce7ce621b2a (diff) |
ONOSFW-171
O/S-SFC-ONOS scenario documentation
Change-Id: I51ae1cf736ea24ab6680f8edca1b2bf5dd598365
Signed-off-by: CNlucius <lukai1@huawei.com>
Diffstat (limited to 'framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective')
10 files changed, 0 insertions, 1977 deletions
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/FlowObjectiveManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/FlowObjectiveManager.java deleted file mode 100644 index 33200b1a..00000000 --- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/FlowObjectiveManager.java +++ /dev/null @@ -1,442 +0,0 @@ -/* - * Copyright 2015 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.net.flowobjective.impl; - -import com.google.common.collect.Maps; -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.Reference; -import org.apache.felix.scr.annotations.ReferenceCardinality; -import org.apache.felix.scr.annotations.Service; -import org.onlab.osgi.DefaultServiceDirectory; -import org.onlab.osgi.ServiceDirectory; -import org.onlab.util.ItemNotFoundException; -import org.onosproject.cluster.ClusterService; -import org.onosproject.mastership.MastershipEvent; -import org.onosproject.mastership.MastershipListener; -import org.onosproject.mastership.MastershipService; -import org.onosproject.net.DeviceId; -import org.onosproject.net.behaviour.Pipeliner; -import org.onosproject.net.behaviour.PipelinerContext; -import org.onosproject.net.device.DeviceEvent; -import org.onosproject.net.device.DeviceListener; -import org.onosproject.net.device.DeviceService; -import org.onosproject.net.driver.DefaultDriverProviderService; -import org.onosproject.net.driver.DriverHandler; -import org.onosproject.net.driver.DriverService; -import org.onosproject.net.flow.FlowRuleService; -import org.onosproject.net.flowobjective.FilteringObjective; -import org.onosproject.net.flowobjective.FlowObjectiveService; -import org.onosproject.net.flowobjective.FlowObjectiveStore; -import org.onosproject.net.flowobjective.FlowObjectiveStoreDelegate; -import org.onosproject.net.flowobjective.ForwardingObjective; -import org.onosproject.net.flowobjective.NextObjective; -import org.onosproject.net.flowobjective.Objective; -import org.onosproject.net.flowobjective.ObjectiveError; -import org.onosproject.net.flowobjective.ObjectiveEvent; -import org.onosproject.net.group.GroupService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Collections; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutorService; - -import static com.google.common.base.Preconditions.checkNotNull; -import static java.util.concurrent.Executors.newFixedThreadPool; -import static org.onlab.util.Tools.groupedThreads; -import static org.onosproject.security.AppGuard.checkPermission; -import static org.onosproject.security.AppPermission.Type.*; - - - -/** - * Provides implementation of the flow objective programming service. - */ -@Component(immediate = true) -@Service -public class FlowObjectiveManager implements FlowObjectiveService { - - public static final int INSTALL_RETRY_ATTEMPTS = 5; - public static final long INSTALL_RETRY_INTERVAL = 1000; // ms - - private final Logger log = LoggerFactory.getLogger(getClass()); - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected DriverService driverService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected DeviceService deviceService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected MastershipService mastershipService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected ClusterService clusterService; - - // Note: The following dependencies are added on behalf of the pipeline - // driver behaviours to assure these services are available for their - // initialization. - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected FlowRuleService flowRuleService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected GroupService groupService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected FlowObjectiveStore flowObjectiveStore; - - // Note: This must remain an optional dependency to allow re-install of default drivers. - // Note: For now disabled until we can move to OPTIONAL_UNARY dependency - // @Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY, policy = ReferencePolicy.DYNAMIC) - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected DefaultDriverProviderService defaultDriverService; - - private final FlowObjectiveStoreDelegate delegate = new InternalStoreDelegate(); - - private final Map<DeviceId, DriverHandler> driverHandlers = Maps.newConcurrentMap(); - private final Map<DeviceId, Pipeliner> pipeliners = Maps.newConcurrentMap(); - - private final PipelinerContext context = new InnerPipelineContext(); - private final MastershipListener mastershipListener = new InnerMastershipListener(); - private final DeviceListener deviceListener = new InnerDeviceListener(); - - protected ServiceDirectory serviceDirectory = new DefaultServiceDirectory(); - - private Map<Integer, Set<PendingNext>> pendingForwards = Maps.newConcurrentMap(); - - private ExecutorService executorService; - - @Activate - protected void activate() { - executorService = newFixedThreadPool(4, groupedThreads("onos/objective-installer", "%d")); - flowObjectiveStore.setDelegate(delegate); - mastershipService.addListener(mastershipListener); - deviceService.addListener(deviceListener); - deviceService.getDevices().forEach(device -> setupPipelineHandler(device.id())); - log.info("Started"); - } - - @Deactivate - protected void deactivate() { - flowObjectiveStore.unsetDelegate(delegate); - mastershipService.removeListener(mastershipListener); - deviceService.removeListener(deviceListener); - executorService.shutdown(); - pipeliners.clear(); - driverHandlers.clear(); - log.info("Stopped"); - } - - /** - * Task that passes the flow objective down to the driver. The task will - * make a few attempts to find the appropriate driver, then eventually give - * up and report an error if no suitable driver could be found. - */ - private class ObjectiveInstaller implements Runnable { - private final DeviceId deviceId; - private final Objective objective; - - private final int numAttempts; - - public ObjectiveInstaller(DeviceId deviceId, Objective objective) { - this(deviceId, objective, 1); - } - - public ObjectiveInstaller(DeviceId deviceId, Objective objective, int attemps) { - this.deviceId = checkNotNull(deviceId); - this.objective = checkNotNull(objective); - this.numAttempts = checkNotNull(attemps); - } - - @Override - public void run() { - try { - Pipeliner pipeliner = getDevicePipeliner(deviceId); - - if (pipeliner != null) { - if (objective instanceof NextObjective) { - pipeliner.next((NextObjective) objective); - } else if (objective instanceof ForwardingObjective) { - pipeliner.forward((ForwardingObjective) objective); - } else { - pipeliner.filter((FilteringObjective) objective); - } - } else if (numAttempts < INSTALL_RETRY_ATTEMPTS) { - Thread.sleep(INSTALL_RETRY_INTERVAL); - executorService.submit(new ObjectiveInstaller(deviceId, objective, numAttempts + 1)); - } else { - // Otherwise we've tried a few times and failed, report an - // error back to the user. - objective.context().ifPresent( - c -> c.onError(objective, ObjectiveError.DEVICEMISSING)); - } - } catch (Exception e) { - log.warn("Exception while installing flow objective", e); - } - } - } - - @Override - public void filter(DeviceId deviceId, FilteringObjective filteringObjective) { - checkPermission(FLOWRULE_WRITE); - executorService.submit(new ObjectiveInstaller(deviceId, filteringObjective)); - } - - @Override - public void forward(DeviceId deviceId, ForwardingObjective forwardingObjective) { - checkPermission(FLOWRULE_WRITE); - if (queueObjective(deviceId, forwardingObjective)) { - return; - } - executorService.submit(new ObjectiveInstaller(deviceId, forwardingObjective)); - } - - @Override - public void next(DeviceId deviceId, NextObjective nextObjective) { - checkPermission(FLOWRULE_WRITE); - executorService.submit(new ObjectiveInstaller(deviceId, nextObjective)); - } - - @Override - public int allocateNextId() { - checkPermission(FLOWRULE_WRITE); - return flowObjectiveStore.allocateNextId(); - } - - @Override - public void initPolicy(String policy) {} - - private boolean queueObjective(DeviceId deviceId, ForwardingObjective fwd) { - if (fwd.nextId() != null && - flowObjectiveStore.getNextGroup(fwd.nextId()) == null) { - log.trace("Queuing forwarding objective for nextId {}", fwd.nextId()); - // TODO: change to computeIfAbsent - Set<PendingNext> newset = Collections.newSetFromMap( - new ConcurrentHashMap<PendingNext, Boolean>()); - newset.add(new PendingNext(deviceId, fwd)); - Set<PendingNext> pnext = pendingForwards.putIfAbsent(fwd.nextId(), newset); - if (pnext != null) { - pnext.add(new PendingNext(deviceId, fwd)); - } - return true; - } - return false; - } - - // Retrieves the device pipeline behaviour from the cache. - private Pipeliner getDevicePipeliner(DeviceId deviceId) { - return pipeliners.get(deviceId); - } - - private void setupPipelineHandler(DeviceId deviceId) { - if (defaultDriverService == null) { - // We're not ready to go to work yet. - return; - } - - // Attempt to lookup the handler in the cache - DriverHandler handler = driverHandlers.get(deviceId); - cTime = now(); - - if (handler == null) { - try { - // Otherwise create it and if it has pipeline behaviour, cache it - handler = driverService.createHandler(deviceId); - dTime = now(); - if (!handler.driver().hasBehaviour(Pipeliner.class)) { - log.warn("Pipeline behaviour not supported for device {}", - deviceId); - return; - } - } catch (ItemNotFoundException e) { - log.warn("No applicable driver for device {}", deviceId); - return; - } - - driverHandlers.put(deviceId, handler); - eTime = now(); - } - - // Always (re)initialize the pipeline behaviour - log.info("Driver {} bound to device {} ... initializing driver", - handler.driver().name(), deviceId); - hTime = now(); - Pipeliner pipeliner = handler.behaviour(Pipeliner.class); - hbTime = now(); - pipeliner.init(deviceId, context); - pipeliners.putIfAbsent(deviceId, pipeliner); - } - - // Triggers driver setup when the local node becomes a device master. - private class InnerMastershipListener implements MastershipListener { - @Override - public void event(MastershipEvent event) { - switch (event.type()) { - case MASTER_CHANGED: - log.debug("mastership changed on device {}", event.subject()); - start = now(); - if (deviceService.isAvailable(event.subject())) { - setupPipelineHandler(event.subject()); - } - stopWatch(); - break; - case BACKUPS_CHANGED: - break; - default: - break; - } - } - } - - // Triggers driver setup when a device is (re)detected. - private class InnerDeviceListener implements DeviceListener { - @Override - public void event(DeviceEvent event) { - switch (event.type()) { - case DEVICE_ADDED: - case DEVICE_AVAILABILITY_CHANGED: - log.debug("Device either added or availability changed {}", - event.subject().id()); - start = now(); - if (deviceService.isAvailable(event.subject().id())) { - log.debug("Device is now available {}", event.subject().id()); - setupPipelineHandler(event.subject().id()); - } - stopWatch(); - break; - case DEVICE_UPDATED: - break; - case DEVICE_REMOVED: - break; - case DEVICE_SUSPENDED: - break; - case PORT_ADDED: - break; - case PORT_UPDATED: - break; - case PORT_REMOVED: - break; - default: - break; - } - } - } - - // Temporary mechanism to monitor pipeliner setup time-cost; there are - // intermittent time where this takes in excess of 2 seconds. Why? - private long start = 0, totals = 0, count = 0; - private long cTime, dTime, eTime, hTime, hbTime; - private static final long LIMIT = 500; - - private long now() { - return System.currentTimeMillis(); - } - - private void stopWatch() { - long duration = System.currentTimeMillis() - start; - totals += duration; - count += 1; - if (duration > LIMIT) { - log.info("Pipeline setup took {} ms; avg {} ms; cTime={}, dTime={}, eTime={}, hTime={}, hbTime={}", - duration, totals / count, diff(cTime), diff(dTime), diff(eTime), diff(hTime), diff(hbTime)); - } - } - - private long diff(long bTime) { - long diff = bTime - start; - return diff < 0 ? 0 : diff; - } - - // Processing context for initializing pipeline driver behaviours. - private class InnerPipelineContext implements PipelinerContext { - @Override - public ServiceDirectory directory() { - return serviceDirectory; - } - - @Override - public FlowObjectiveStore store() { - return flowObjectiveStore; - } - } - - private class InternalStoreDelegate implements FlowObjectiveStoreDelegate { - @Override - public void notify(ObjectiveEvent event) { - log.debug("Received notification of obj event {}", event); - Set<PendingNext> pending = pendingForwards.remove(event.subject()); - - if (pending == null) { - log.debug("Nothing pending for this obj event"); - return; - } - - log.debug("Processing pending forwarding objectives {}", pending.size()); - - pending.forEach(p -> getDevicePipeliner(p.deviceId()) - .forward(p.forwardingObjective())); - - } - } - - /** - * Data class used to hold a pending forwarding objective that could not - * be processed because the associated next object was not present. - */ - private class PendingNext { - private final DeviceId deviceId; - private final ForwardingObjective fwd; - - public PendingNext(DeviceId deviceId, ForwardingObjective fwd) { - this.deviceId = deviceId; - this.fwd = fwd; - } - - public DeviceId deviceId() { - return deviceId; - } - - public ForwardingObjective forwardingObjective() { - return fwd; - } - - @Override - public int hashCode() { - return Objects.hash(deviceId, fwd); - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof PendingNext)) { - return false; - } - final PendingNext other = (PendingNext) obj; - if (this.deviceId.equals(other.deviceId) && - this.fwd.equals(other.fwd)) { - return true; - } - return false; - } - } -} diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FilterTable.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FilterTable.java deleted file mode 100644 index b46ce8b3..00000000 --- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FilterTable.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2015 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.net.flowobjective.impl.composition; - -import org.onosproject.net.flowobjective.FilteringObjective; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Provides a table to store Fitler. - */ -public class FilterTable { - - protected Map<Integer, FilteringObjective> filterMap; - - public FilterTable() { - this.filterMap = new HashMap<>(); - } - - public List<FilteringObjective> updateFilter(FilteringObjective filteringObjective) { - List<FilteringObjective> updates = new ArrayList<>(); - switch (filteringObjective.op()) { - case ADD: - this.filterMap.put(filteringObjective.id(), filteringObjective); - updates.add(filteringObjective); - break; - case REMOVE: - this.filterMap.remove(filteringObjective.id()); - updates.add(filteringObjective); - break; - default: - break; - } - return updates; - } - - public List<FilteringObjective> updateFilter(List<FilteringObjective> filteringObjectives) { - List<FilteringObjective> updates = new ArrayList<>(); - for (FilteringObjective filteringObjective : filteringObjectives) { - updates.addAll(this.updateFilter(filteringObjective)); - } - return updates; - } - -} diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FlowObjectiveCompositionManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FlowObjectiveCompositionManager.java deleted file mode 100644 index 3ef98bd8..00000000 --- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FlowObjectiveCompositionManager.java +++ /dev/null @@ -1,439 +0,0 @@ -/* - * Copyright 2015 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.net.flowobjective.impl.composition; - -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -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.Reference; -import org.apache.felix.scr.annotations.ReferenceCardinality; -import org.apache.felix.scr.annotations.Service; -import org.onlab.osgi.DefaultServiceDirectory; -import org.onlab.osgi.ServiceDirectory; -import org.onlab.util.ItemNotFoundException; -import org.onosproject.cluster.ClusterService; -import org.onosproject.mastership.MastershipEvent; -import org.onosproject.mastership.MastershipListener; -import org.onosproject.mastership.MastershipService; -import org.onosproject.net.DeviceId; -import org.onosproject.net.behaviour.Pipeliner; -import org.onosproject.net.behaviour.PipelinerContext; -import org.onosproject.net.device.DeviceEvent; -import org.onosproject.net.device.DeviceListener; -import org.onosproject.net.device.DeviceService; -import org.onosproject.net.driver.DefaultDriverProviderService; -import org.onosproject.net.driver.DriverHandler; -import org.onosproject.net.driver.DriverService; -import org.onosproject.net.flow.FlowRuleService; -import org.onosproject.net.flow.criteria.Criterion; -import org.onosproject.net.flow.instructions.Instruction; -import org.onosproject.net.flowobjective.FilteringObjective; -import org.onosproject.net.flowobjective.FlowObjectiveService; -import org.onosproject.net.flowobjective.FlowObjectiveStore; -import org.onosproject.net.flowobjective.FlowObjectiveStoreDelegate; -import org.onosproject.net.flowobjective.ForwardingObjective; -import org.onosproject.net.flowobjective.NextObjective; -import org.onosproject.net.flowobjective.Objective; -import org.onosproject.net.flowobjective.ObjectiveError; -import org.onosproject.net.flowobjective.ObjectiveEvent; -import org.onosproject.net.group.GroupService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ExecutorService; - -import static com.google.common.base.Preconditions.checkNotNull; -import static java.util.concurrent.Executors.newFixedThreadPool; -import static org.onlab.util.Tools.groupedThreads; -import static org.onosproject.security.AppGuard.checkPermission; -import static org.onosproject.security.AppPermission.Type.*; - - -/** - * Provides implementation of the flow objective programming service with composition feature. - * - * Note: This is an experimental, alternative implementation of the FlowObjectiveManager - * that supports composition. It can be enabled by setting the enable flag below to true, - * and you should also add "enabled = false" to the FlowObjectiveManager. - * - * The implementation relies a FlowObjectiveCompositionTree that is not yet distributed, - * so it will not have high availability and may break if device mastership changes. - * Therefore, it is safest to use this component in a single instance scenario. - * This comment will be removed when a distributed implementation is available. - */ -@Component(immediate = true, enabled = false) -@Service -public class FlowObjectiveCompositionManager implements FlowObjectiveService { - - public enum PolicyOperator { - Parallel, - Sequential, - Override, - Application - } - - public static final int INSTALL_RETRY_ATTEMPTS = 5; - public static final long INSTALL_RETRY_INTERVAL = 1000; // ms - - private final Logger log = LoggerFactory.getLogger(getClass()); - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected DriverService driverService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected DeviceService deviceService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected MastershipService mastershipService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected ClusterService clusterService; - - // Note: The following dependencies are added on behalf of the pipeline - // driver behaviours to assure these services are available for their - // initialization. - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected FlowRuleService flowRuleService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected GroupService groupService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected FlowObjectiveStore flowObjectiveStore; - - // Note: This must remain an optional dependency to allow re-install of default drivers. - // Note: For now disabled until we can move to OPTIONAL_UNARY dependency - // @Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY, policy = ReferencePolicy.DYNAMIC) - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected DefaultDriverProviderService defaultDriverService; - - private final FlowObjectiveStoreDelegate delegate = new InternalStoreDelegate(); - - private final Map<DeviceId, DriverHandler> driverHandlers = Maps.newConcurrentMap(); - private final Map<DeviceId, Pipeliner> pipeliners = Maps.newConcurrentMap(); - - private final PipelinerContext context = new InnerPipelineContext(); - private final MastershipListener mastershipListener = new InnerMastershipListener(); - private final DeviceListener deviceListener = new InnerDeviceListener(); - - protected ServiceDirectory serviceDirectory = new DefaultServiceDirectory(); - - private Map<Integer, Set<PendingNext>> pendingForwards = Maps.newConcurrentMap(); - - private ExecutorService executorService; - - private String policy; - private Map<DeviceId, FlowObjectiveCompositionTree> deviceCompositionTreeMap; - - @Activate - protected void activate() { - executorService = newFixedThreadPool(4, groupedThreads("onos/objective-installer", "%d")); - flowObjectiveStore.setDelegate(delegate); - mastershipService.addListener(mastershipListener); - deviceService.addListener(deviceListener); - deviceService.getDevices().forEach(device -> setupPipelineHandler(device.id())); - deviceCompositionTreeMap = Maps.newConcurrentMap(); - log.info("Started"); - } - - @Deactivate - protected void deactivate() { - flowObjectiveStore.unsetDelegate(delegate); - mastershipService.removeListener(mastershipListener); - deviceService.removeListener(deviceListener); - executorService.shutdown(); - pipeliners.clear(); - driverHandlers.clear(); - deviceCompositionTreeMap.clear(); - log.info("Stopped"); - } - - /** - * Task that passes the flow objective down to the driver. The task will - * make a few attempts to find the appropriate driver, then eventually give - * up and report an error if no suitable driver could be found. - */ - private class ObjectiveInstaller implements Runnable { - private final DeviceId deviceId; - private final Objective objective; - - private final int numAttempts; - - public ObjectiveInstaller(DeviceId deviceId, Objective objective) { - this(deviceId, objective, 1); - } - - public ObjectiveInstaller(DeviceId deviceId, Objective objective, int attemps) { - this.deviceId = checkNotNull(deviceId); - this.objective = checkNotNull(objective); - this.numAttempts = checkNotNull(attemps); - } - - @Override - public void run() { - try { - Pipeliner pipeliner = getDevicePipeliner(deviceId); - - if (pipeliner != null) { - if (objective instanceof NextObjective) { - pipeliner.next((NextObjective) objective); - } else if (objective instanceof ForwardingObjective) { - pipeliner.forward((ForwardingObjective) objective); - } else { - pipeliner.filter((FilteringObjective) objective); - } - } else if (numAttempts < INSTALL_RETRY_ATTEMPTS) { - Thread.sleep(INSTALL_RETRY_INTERVAL); - executorService.submit(new ObjectiveInstaller(deviceId, objective, numAttempts + 1)); - } else { - // Otherwise we've tried a few times and failed, report an - // error back to the user. - objective.context().ifPresent( - c -> c.onError(objective, ObjectiveError.DEVICEMISSING)); - } - } catch (Exception e) { - log.warn("Exception while installing flow objective", e); - } - } - } - - @Override - public void filter(DeviceId deviceId, FilteringObjective filteringObjective) { - checkPermission(FLOWRULE_WRITE); - - List<FilteringObjective> filteringObjectives - = this.deviceCompositionTreeMap.get(deviceId).updateFilter(filteringObjective); - for (FilteringObjective tmp : filteringObjectives) { - executorService.submit(new ObjectiveInstaller(deviceId, tmp)); - } - } - - @Override - public void forward(DeviceId deviceId, ForwardingObjective forwardingObjective) { - checkPermission(FLOWRULE_WRITE); - - if (queueObjective(deviceId, forwardingObjective)) { - return; - } - List<ForwardingObjective> forwardingObjectives - = this.deviceCompositionTreeMap.get(deviceId).updateForward(forwardingObjective); - for (ForwardingObjective tmp : forwardingObjectives) { - executorService.submit(new ObjectiveInstaller(deviceId, tmp)); - } - } - - @Override - public void next(DeviceId deviceId, NextObjective nextObjective) { - checkPermission(FLOWRULE_WRITE); - - List<NextObjective> nextObjectives = this.deviceCompositionTreeMap.get(deviceId).updateNext(nextObjective); - for (NextObjective tmp : nextObjectives) { - executorService.submit(new ObjectiveInstaller(deviceId, tmp)); - } - } - - @Override - public int allocateNextId() { - checkPermission(FLOWRULE_WRITE); - - return flowObjectiveStore.allocateNextId(); - } - - private boolean queueObjective(DeviceId deviceId, ForwardingObjective fwd) { - if (fwd.nextId() != null && - flowObjectiveStore.getNextGroup(fwd.nextId()) == null) { - log.trace("Queuing forwarding objective for nextId {}", fwd.nextId()); - if (pendingForwards.putIfAbsent(fwd.nextId(), - Sets.newHashSet(new PendingNext(deviceId, fwd))) != null) { - Set<PendingNext> pending = pendingForwards.get(fwd.nextId()); - pending.add(new PendingNext(deviceId, fwd)); - } - return true; - } - return false; - } - - @Override - public void initPolicy(String policy) { - this.policy = policy; - deviceService.getDevices().forEach(device -> - this.deviceCompositionTreeMap.put(device.id(), FlowObjectiveCompositionUtil.parsePolicyString(policy))); - log.info("Initialize policy {}", policy); - } - - // Retrieves the device pipeline behaviour from the cache. - private Pipeliner getDevicePipeliner(DeviceId deviceId) { - Pipeliner pipeliner = pipeliners.get(deviceId); - return pipeliner; - } - - private void setupPipelineHandler(DeviceId deviceId) { - if (defaultDriverService == null) { - // We're not ready to go to work yet. - return; - } - - // Attempt to lookup the handler in the cache - DriverHandler handler = driverHandlers.get(deviceId); - if (handler == null) { - try { - // Otherwise create it and if it has pipeline behaviour, cache it - handler = driverService.createHandler(deviceId); - if (!handler.driver().hasBehaviour(Pipeliner.class)) { - log.warn("Pipeline behaviour not supported for device {}", - deviceId); - return; - } - } catch (ItemNotFoundException e) { - log.warn("No applicable driver for device {}", deviceId); - return; - } - - driverHandlers.put(deviceId, handler); - } - - // Always (re)initialize the pipeline behaviour - log.info("Driver {} bound to device {} ... initializing driver", - handler.driver().name(), deviceId); - Pipeliner pipeliner = handler.behaviour(Pipeliner.class); - pipeliner.init(deviceId, context); - pipeliners.putIfAbsent(deviceId, pipeliner); - } - - // Triggers driver setup when the local node becomes a device master. - private class InnerMastershipListener implements MastershipListener { - @Override - public void event(MastershipEvent event) { - switch (event.type()) { - case MASTER_CHANGED: - log.debug("mastership changed on device {}", event.subject()); - if (deviceService.isAvailable(event.subject())) { - setupPipelineHandler(event.subject()); - } - break; - case BACKUPS_CHANGED: - break; - default: - break; - } - } - } - - // Triggers driver setup when a device is (re)detected. - private class InnerDeviceListener implements DeviceListener { - @Override - public void event(DeviceEvent event) { - switch (event.type()) { - case DEVICE_ADDED: - case DEVICE_AVAILABILITY_CHANGED: - log.debug("Device either added or availability changed {}", - event.subject().id()); - if (deviceService.isAvailable(event.subject().id())) { - log.debug("Device is now available {}", event.subject().id()); - setupPipelineHandler(event.subject().id()); - } - break; - case DEVICE_UPDATED: - break; - case DEVICE_REMOVED: - break; - case DEVICE_SUSPENDED: - break; - case PORT_ADDED: - break; - case PORT_UPDATED: - break; - case PORT_REMOVED: - break; - default: - break; - } - } - } - - // Processing context for initializing pipeline driver behaviours. - private class InnerPipelineContext implements PipelinerContext { - @Override - public ServiceDirectory directory() { - return serviceDirectory; - } - - @Override - public FlowObjectiveStore store() { - return flowObjectiveStore; - } - } - - private class InternalStoreDelegate implements FlowObjectiveStoreDelegate { - @Override - public void notify(ObjectiveEvent event) { - log.debug("Received notification of obj event {}", event); - Set<PendingNext> pending = pendingForwards.remove(event.subject()); - - if (pending == null) { - log.debug("Nothing pending for this obj event"); - return; - } - - log.debug("Processing pending forwarding objectives {}", pending.size()); - - pending.forEach(p -> getDevicePipeliner(p.deviceId()) - .forward(p.forwardingObjective())); - - } - } - - /** - * Data class used to hold a pending forwarding objective that could not - * be processed because the associated next object was not present. - */ - private class PendingNext { - private final DeviceId deviceId; - private final ForwardingObjective fwd; - - public PendingNext(DeviceId deviceId, ForwardingObjective fwd) { - this.deviceId = deviceId; - this.fwd = fwd; - } - - public DeviceId deviceId() { - return deviceId; - } - - public ForwardingObjective forwardingObjective() { - return fwd; - } - } - - public static String forwardingObjectiveToString(ForwardingObjective forwardingObjective) { - String str = forwardingObjective.priority() + " "; - str += "selector( "; - for (Criterion criterion : forwardingObjective.selector().criteria()) { - str += criterion + " "; - } - str += ") treatment( "; - for (Instruction instruction : forwardingObjective.treatment().allInstructions()) { - str += instruction + " "; - } - str += ")"; - return str; - } -} diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FlowObjectiveCompositionTree.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FlowObjectiveCompositionTree.java deleted file mode 100644 index 152622b2..00000000 --- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FlowObjectiveCompositionTree.java +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright 2015 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.net.flowobjective.impl.composition; - -import org.onosproject.net.flowobjective.FilteringObjective; -import org.onosproject.net.flowobjective.ForwardingObjective; -import org.onosproject.net.flowobjective.NextObjective; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -/** - * Provides a policy tree to store all flow tables for each device. - * - * Note: This class uses in-memory structures and is not yet distributed. - */ -public class FlowObjectiveCompositionTree { - - public FlowObjectiveCompositionManager.PolicyOperator operator; - public FlowObjectiveCompositionTree leftChild; - public FlowObjectiveCompositionTree rightChild; - public short applicationId; - protected FilterTable filterTable; - protected ForwardTable forwardTable; - protected NextTable nextTable; - - protected int priorityMultiplier; - protected int priorityAddend; - - public FlowObjectiveCompositionTree(short applicationId) { - this.operator = FlowObjectiveCompositionManager.PolicyOperator.Application; - this.leftChild = null; - this.rightChild = null; - this.applicationId = applicationId; - this.filterTable = new FilterTable(); - this.forwardTable = new ForwardTable(); - this.nextTable = new NextTable(); - this.priorityMultiplier = 10; - this.priorityAddend = 10; - } - - public FlowObjectiveCompositionTree(Character ch) { - switch (ch) { - case '+': - this.operator = FlowObjectiveCompositionManager.PolicyOperator.Parallel; - break; - case '>': - this.operator = FlowObjectiveCompositionManager.PolicyOperator.Sequential; - break; - case '/': - this.operator = FlowObjectiveCompositionManager.PolicyOperator.Override; - break; - default: - this.operator = FlowObjectiveCompositionManager.PolicyOperator.Application; - break; - } - this.leftChild = null; - this.rightChild = null; - this.applicationId = (short) -1; - this.filterTable = new FilterTable(); - this.forwardTable = new ForwardTable(); - this.nextTable = new NextTable(); - this.priorityMultiplier = 10; - this.priorityAddend = 10; - } - - protected List<FilteringObjective> updateFilter(FilteringObjective filteringObjective) { - switch (this.operator) { - case Parallel: - return updateFilterParallel(filteringObjective); - case Sequential: - return updateFilterSequential(filteringObjective); - case Override: - return updateFilterOverride(filteringObjective); - case Application: - if (filteringObjective.appId().id() == this.applicationId) { - return this.filterTable.updateFilter(filteringObjective); - } else { - return new ArrayList<>(); - } - default: - return new ArrayList<>(); - } - } - - // Parallel composition: the filter set is the union of the children - protected List<FilteringObjective> updateFilterParallel(FilteringObjective filteringObjective) { - List<FilteringObjective> leftUpdates = this.leftChild.updateFilter(filteringObjective); - List<FilteringObjective> rightUpdates = this.rightChild.updateFilter(filteringObjective); - - List<FilteringObjective> updates = new ArrayList<>(); - updates.addAll(leftUpdates); - updates.addAll(rightUpdates); - - return this.filterTable.updateFilter(updates); - } - - // Sequential composition: the filter set is the filter set of the left child - protected List<FilteringObjective> updateFilterSequential(FilteringObjective filteringObjective) { - List<FilteringObjective> leftUpdates = this.leftChild.updateFilter(filteringObjective); - List<FilteringObjective> rightUpdates = this.rightChild.updateFilter(filteringObjective); - return this.filterTable.updateFilter(leftUpdates); - } - - // Override composition: the filter set is the filter set of the left child - protected List<FilteringObjective> updateFilterOverride(FilteringObjective filteringObjective) { - List<FilteringObjective> leftUpdates = this.leftChild.updateFilter(filteringObjective); - List<FilteringObjective> rightUpdates = this.rightChild.updateFilter(filteringObjective); - return this.filterTable.updateFilter(leftUpdates); - } - - public List<ForwardingObjective> updateForward(ForwardingObjective forwardingObjective) { - return this.updateForwardNode(forwardingObjective).toForwardingObjectiveList(); - } - - public ForwardUpdateTable updateForwardNode(ForwardingObjective forwardingObjective) { - switch (this.operator) { - case Parallel: - case Sequential: - case Override: - return updateForwardComposition(forwardingObjective); - case Application: - if (forwardingObjective.appId().id() == this.applicationId) { - return this.forwardTable.updateForward(forwardingObjective); - } else { - return (new ForwardUpdateTable()); - } - default: - return (new ForwardUpdateTable()); - } - } - - protected ForwardUpdateTable updateForwardComposition(ForwardingObjective forwardingObjective) { - ForwardUpdateTable leftUpdates = this.leftChild.updateForwardNode(forwardingObjective); - ForwardUpdateTable rightUpdates = this.rightChild.updateForwardNode(forwardingObjective); - - List<ForwardingObjective> addUpdates = new ArrayList<>(); - List<ForwardingObjective> removeUpdates = new ArrayList<>(); - // Handle ADD - if (this.operator == FlowObjectiveCompositionManager.PolicyOperator.Parallel - || this.operator == FlowObjectiveCompositionManager.PolicyOperator.Sequential) { - for (ForwardingObjective fo1 : leftUpdates.addObjectives) { - for (ForwardingObjective fo2 : this.rightChild.forwardTable.getForwardingObjectives()) { - ForwardingObjective composedFo = null; - if (this.operator == FlowObjectiveCompositionManager.PolicyOperator.Parallel) { - composedFo = FlowObjectiveCompositionUtil.composeParallel(fo1, fo2); - } else { - composedFo = FlowObjectiveCompositionUtil.composeSequential(fo1, fo2, this.priorityMultiplier); - } - if (composedFo != null) { - addUpdates.add(composedFo); - this.leftChild.forwardTable.addGeneratedParentForwardingObjective(fo1, composedFo); - this.rightChild.forwardTable.addGeneratedParentForwardingObjective(fo2, composedFo); - } - } - } - Collection<ForwardingObjective> leftTableWithoutAdd = FlowObjectiveCompositionUtil - .minusForwardingObjectives(this.leftChild.forwardTable.getForwardingObjectives(), - leftUpdates.addObjectives); - for (ForwardingObjective fo1 : leftTableWithoutAdd) { - for (ForwardingObjective fo2 : rightUpdates.addObjectives) { - ForwardingObjective composedFo = null; - if (this.operator == FlowObjectiveCompositionManager.PolicyOperator.Parallel) { - composedFo = FlowObjectiveCompositionUtil.composeParallel(fo1, fo2); - } else { - composedFo = FlowObjectiveCompositionUtil.composeSequential(fo1, fo2, this.priorityMultiplier); - } - if (composedFo != null) { - addUpdates.add(composedFo); - this.leftChild.forwardTable.addGeneratedParentForwardingObjective(fo1, composedFo); - this.rightChild.forwardTable.addGeneratedParentForwardingObjective(fo2, composedFo); - } - } - } - } else { - for (ForwardingObjective fo : leftUpdates.addObjectives) { - ForwardingObjective composedFo = FlowObjectiveCompositionUtil.composeOverride(fo, this.priorityAddend); - addUpdates.add(composedFo); - this.leftChild.forwardTable.addGeneratedParentForwardingObjective(fo, composedFo); - } - for (ForwardingObjective fo : rightUpdates.addObjectives) { - ForwardingObjective composedFo = FlowObjectiveCompositionUtil.composeOverride(fo, 0); - addUpdates.add(composedFo); - this.rightChild.forwardTable.addGeneratedParentForwardingObjective(fo, composedFo); - } - } - - // Handle REMOVE - for (ForwardingObjective fo : leftUpdates.removeObjectives) { - List<ForwardingObjective> fos = this.leftChild.forwardTable - .getGeneratedParentForwardingObjectiveForRemove(fo); - removeUpdates.addAll(fos); - } - this.leftChild.forwardTable.deleteGeneratedParentForwardingObjective(leftUpdates.removeObjectives); - for (ForwardingObjective fo : rightUpdates.removeObjectives) { - List<ForwardingObjective> fos = this.rightChild.forwardTable - .getGeneratedParentForwardingObjectiveForRemove(fo); - removeUpdates.addAll(fos); - } - this.rightChild.forwardTable.deleteGeneratedParentForwardingObjective(rightUpdates.removeObjectives); - - ForwardUpdateTable updates = new ForwardUpdateTable(); - updates.addUpdateTable(this.forwardTable.updateForward(addUpdates)); - updates.addUpdateTable(this.forwardTable.updateForward(removeUpdates)); - return updates; - } - - public List<NextObjective> updateNext(NextObjective nextObjective) { - switch (this.operator) { - case Parallel: - case Sequential: - case Override: - return updateNextComposition(nextObjective); - case Application: - if (nextObjective.appId().id() == this.applicationId) { - return this.nextTable.updateNext(nextObjective); - } else { - return new ArrayList<>(); - } - default: - return new ArrayList<>(); - } - } - - // Next: the union of the children - protected List<NextObjective> updateNextComposition(NextObjective nextObjective) { - List<NextObjective> leftUpdates = this.leftChild.updateNext(nextObjective); - List<NextObjective> rightUpdates = this.rightChild.updateNext(nextObjective); - - List<NextObjective> updates = new ArrayList<>(); - updates.addAll(leftUpdates); - updates.addAll(rightUpdates); - - return this.nextTable.updateNext(updates); - } - - @Override - public String toString() { - String str = null; - switch (this.operator) { - case Parallel: - str = "(" + this.leftChild + "+" + this.rightChild + ")"; - break; - case Sequential: - str = "(" + this.leftChild + ">" + this.rightChild + ")"; - break; - case Override: - str = "(" + this.leftChild + "/" + this.rightChild + ")"; - break; - default: - str = " " + applicationId + " "; - break; - } - return str; - } - -} diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FlowObjectiveCompositionUtil.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FlowObjectiveCompositionUtil.java deleted file mode 100644 index 0a1af6f5..00000000 --- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FlowObjectiveCompositionUtil.java +++ /dev/null @@ -1,508 +0,0 @@ -/* - * Copyright 2015 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.net.flowobjective.impl.composition; - -import org.onlab.packet.IpPrefix; -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.flow.criteria.Criterion; -import org.onosproject.net.flow.criteria.LambdaCriterion; -import org.onosproject.net.flow.criteria.OchSignalCriterion; -import org.onosproject.net.flow.criteria.EthCriterion; -import org.onosproject.net.flow.criteria.VlanIdCriterion; -import org.onosproject.net.flow.criteria.VlanPcpCriterion; -import org.onosproject.net.flow.criteria.MplsCriterion; -import org.onosproject.net.flow.criteria.IPCriterion; -import org.onosproject.net.flow.criteria.IPv6FlowLabelCriterion; -import org.onosproject.net.flow.criteria.OduSignalIdCriterion; -import org.onosproject.net.flow.criteria.Criteria; -import org.onosproject.net.flow.instructions.Instruction; -import org.onosproject.net.flow.instructions.L0ModificationInstruction; -import org.onosproject.net.flow.instructions.L1ModificationInstruction; -import org.onosproject.net.flow.instructions.L2ModificationInstruction; -import org.onosproject.net.flow.instructions.L3ModificationInstruction; -import org.onosproject.net.flowobjective.DefaultForwardingObjective; -import org.onosproject.net.flowobjective.ForwardingObjective; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.Stack; - -/** - * Provide util functions for FlowObjectiveComposition. - */ -public final class FlowObjectiveCompositionUtil { - - private FlowObjectiveCompositionUtil() {} - - // only work with VERSATILE - public static ForwardingObjective composeParallel(ForwardingObjective fo1, ForwardingObjective fo2) { - - TrafficSelector trafficSelector = intersectTrafficSelector(fo1.selector(), fo2.selector()); - if (trafficSelector == null) { - return null; - } - - TrafficTreatment trafficTreatment = unionTrafficTreatment(fo1.treatment(), fo2.treatment()); - - return DefaultForwardingObjective.builder() - .fromApp(fo1.appId()) - .makePermanent() - .withFlag(ForwardingObjective.Flag.VERSATILE) - .withPriority(fo1.priority() + fo2.priority()) - .withSelector(trafficSelector) - .withTreatment(trafficTreatment) - .add(); - } - - public static ForwardingObjective composeSequential(ForwardingObjective fo1, - ForwardingObjective fo2, - int priorityMultiplier) { - - TrafficSelector revertTrafficSelector = revertTreatmentSelector(fo1.treatment(), fo2.selector()); - if (revertTrafficSelector == null) { - return null; - } - - TrafficSelector trafficSelector = intersectTrafficSelector(fo1.selector(), revertTrafficSelector); - if (trafficSelector == null) { - return null; - } - - TrafficTreatment trafficTreatment = unionTrafficTreatment(fo1.treatment(), fo2.treatment()); - - return DefaultForwardingObjective.builder() - .fromApp(fo1.appId()) - .makePermanent() - .withFlag(ForwardingObjective.Flag.VERSATILE) - .withPriority(fo1.priority() * priorityMultiplier + fo2.priority()) - .withSelector(trafficSelector) - .withTreatment(trafficTreatment) - .add(); - } - - public static ForwardingObjective composeOverride(ForwardingObjective fo, int priorityAddend) { - return DefaultForwardingObjective.builder() - .fromApp(fo.appId()) - .makePermanent() - .withFlag(fo.flag()) - .withPriority(fo.priority() + priorityAddend) - .withSelector(fo.selector()) - .withTreatment(fo.treatment()) - .add(); - } - - public static TrafficSelector intersectTrafficSelector(TrafficSelector ts1, TrafficSelector ts2) { - - TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder(); - - Set<Criterion.Type> ts1IntersectTs2 = getTypeSet(ts1); - ts1IntersectTs2.retainAll(getTypeSet(ts2)); - for (Criterion.Type type : ts1IntersectTs2) { - Criterion criterion = intersectCriterion(ts1.getCriterion(type), ts2.getCriterion(type)); - if (criterion == null) { - return null; - } else { - selectorBuilder.add(criterion); - } - } - - Set<Criterion.Type> ts1MinusTs2 = getTypeSet(ts1); - ts1MinusTs2.removeAll(getTypeSet(ts2)); - for (Criterion.Type type : ts1MinusTs2) { - selectorBuilder.add(ts1.getCriterion(type)); - } - - Set<Criterion.Type> ts2MinusTs1 = getTypeSet(ts2); - ts2MinusTs1.removeAll(getTypeSet(ts1)); - for (Criterion.Type type : ts2MinusTs1) { - selectorBuilder.add(ts2.getCriterion(type)); - } - - return selectorBuilder.build(); - } - - public static TrafficTreatment unionTrafficTreatment(TrafficTreatment tt1, TrafficTreatment tt2) { - - TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder(); - - for (Instruction instruction : tt1.allInstructions()) { - treatmentBuilder.add(instruction); - } - - for (Instruction instruction : tt2.allInstructions()) { - treatmentBuilder.add(instruction); - } - - return treatmentBuilder.build(); - } - - //CHECKSTYLE:OFF - public static TrafficSelector revertTreatmentSelector(TrafficTreatment trafficTreatment, - TrafficSelector trafficSelector) { - - TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder(); - - Map<Criterion.Type, Criterion> criterionMap = new HashMap<>(); - for (Criterion criterion : trafficSelector.criteria()) { - criterionMap.put(criterion.type(), criterion); - } - - for (Instruction instruction : trafficTreatment.allInstructions()) { - switch (instruction.type()) { - case DROP: - return null; - case OUTPUT: - break; - case GROUP: - break; - case L0MODIFICATION: { - L0ModificationInstruction l0 = (L0ModificationInstruction) instruction; - switch (l0.subtype()) { - case LAMBDA: - if (criterionMap.containsKey(Criterion.Type.OCH_SIGID)) { - if (((LambdaCriterion) criterionMap.get((Criterion.Type.OCH_SIGID))).lambda() - == ((L0ModificationInstruction.ModLambdaInstruction) l0).lambda()) { - criterionMap.remove(Criterion.Type.OCH_SIGID); - } else { - return null; - } - } else { - break; - } - case OCH: - if (criterionMap.containsKey(Criterion.Type.OCH_SIGID)) { - if (((OchSignalCriterion) criterionMap.get((Criterion.Type.OCH_SIGID))).lambda() - .equals(((L0ModificationInstruction.ModOchSignalInstruction) l0).lambda())) { - criterionMap.remove(Criterion.Type.OCH_SIGID); - } else { - return null; - } - } - default: - break; - } - break; - } - case L1MODIFICATION: { - L1ModificationInstruction l1 = (L1ModificationInstruction) instruction; - switch (l1.subtype()) { - case ODU_SIGID: - if (criterionMap.containsKey(Criterion.Type.ODU_SIGID)) { - if (((OduSignalIdCriterion) criterionMap.get((Criterion.Type.ODU_SIGID))).oduSignalId() - .equals(((L1ModificationInstruction.ModOduSignalIdInstruction) l1) - .oduSignalId())) { - criterionMap.remove(Criterion.Type.ODU_SIGID); - } else { - return null; - } - } - default: - break; - } - break; - } - case L2MODIFICATION: { - L2ModificationInstruction l2 = (L2ModificationInstruction) instruction; - switch (l2.subtype()) { - case ETH_SRC: - if (criterionMap.containsKey(Criterion.Type.ETH_SRC)) { - if (((EthCriterion) criterionMap.get((Criterion.Type.ETH_SRC))).mac() - .equals(((L2ModificationInstruction.ModEtherInstruction) l2).mac())) { - criterionMap.remove(Criterion.Type.ETH_SRC); - } else { - return null; - } - } else { - break; - } - case ETH_DST: - if (criterionMap.containsKey(Criterion.Type.ETH_DST)) { - if (((EthCriterion) criterionMap.get((Criterion.Type.ETH_DST))).mac() - .equals(((L2ModificationInstruction.ModEtherInstruction) l2).mac())) { - criterionMap.remove(Criterion.Type.ETH_DST); - } else { - return null; - } - } else { - break; - } - case VLAN_ID: - if (criterionMap.containsKey(Criterion.Type.VLAN_VID)) { - if (((VlanIdCriterion) criterionMap.get((Criterion.Type.VLAN_VID))).vlanId() - .equals(((L2ModificationInstruction.ModVlanIdInstruction) l2).vlanId())) { - criterionMap.remove(Criterion.Type.VLAN_VID); - } else { - return null; - } - } else { - break; - } - case VLAN_PCP: - if (criterionMap.containsKey(Criterion.Type.VLAN_PCP)) { - if (((VlanPcpCriterion) criterionMap.get((Criterion.Type.VLAN_PCP))).priority() - == ((L2ModificationInstruction.ModVlanPcpInstruction) l2).vlanPcp()) { - criterionMap.remove(Criterion.Type.VLAN_PCP); - } else { - return null; - } - } else { - break; - } - case MPLS_LABEL: - if (criterionMap.containsKey(Criterion.Type.MPLS_LABEL)) { - if (((MplsCriterion) criterionMap.get((Criterion.Type.MPLS_LABEL))).label() - .equals(((L2ModificationInstruction.ModMplsLabelInstruction) l2).mplsLabel())) { - criterionMap.remove(Criterion.Type.ETH_DST); - } else { - return null; - } - } else { - break; - } - default: - break; - } - break; - } - case TABLE: - break; - case L3MODIFICATION: { - L3ModificationInstruction l3 = (L3ModificationInstruction) instruction; - switch (l3.subtype()) { - case IPV4_SRC: - if (criterionMap.containsKey(Criterion.Type.IPV4_SRC)) { - if (((IPCriterion) criterionMap.get(Criterion.Type.IPV4_SRC)).ip() - .contains(((L3ModificationInstruction.ModIPInstruction) l3).ip())) { - criterionMap.remove(Criterion.Type.IPV4_SRC); - } else { - return null; - } - } else { - break; - } - case IPV4_DST: - if (criterionMap.containsKey(Criterion.Type.IPV4_DST)) { - if (((IPCriterion) criterionMap.get(Criterion.Type.IPV4_DST)).ip() - .contains(((L3ModificationInstruction.ModIPInstruction) l3).ip())) { - criterionMap.remove(Criterion.Type.IPV4_DST); - } else { - return null; - } - } else { - break; - } - case IPV6_SRC: - if (criterionMap.containsKey(Criterion.Type.IPV6_SRC)) { - if (((IPCriterion) criterionMap.get(Criterion.Type.IPV6_SRC)).ip() - .contains(((L3ModificationInstruction.ModIPInstruction) l3).ip())) { - criterionMap.remove(Criterion.Type.IPV6_SRC); - } else { - return null; - } - } else { - break; - } - case IPV6_DST: - if (criterionMap.containsKey(Criterion.Type.IPV6_DST)) { - if (((IPCriterion) criterionMap.get(Criterion.Type.IPV6_DST)).ip() - .contains(((L3ModificationInstruction.ModIPInstruction) l3).ip())) { - criterionMap.remove(Criterion.Type.IPV6_DST); - } else { - return null; - } - } else { - break; - } - case IPV6_FLABEL: - if (criterionMap.containsKey(Criterion.Type.IPV6_FLABEL)) { - if (((IPv6FlowLabelCriterion) criterionMap.get(Criterion.Type.IPV6_FLABEL)).flowLabel() - == (((L3ModificationInstruction.ModIPv6FlowLabelInstruction) l3).flowLabel())) { - criterionMap.remove(Criterion.Type.IPV4_SRC); - } else { - return null; - } - } else { - break; - } - default: - break; - } - break; - } - case METADATA: - break; - default: - break; - } - } - - for (Criterion criterion : criterionMap.values()) { - selectorBuilder.add(criterion); - } - - return selectorBuilder.build(); - } - //CHECKSTYLE:ON - - public static Set<Criterion.Type> getTypeSet(TrafficSelector trafficSelector) { - Set<Criterion.Type> typeSet = new HashSet<>(); - for (Criterion criterion : trafficSelector.criteria()) { - typeSet.add(criterion.type()); - } - return typeSet; - } - - public static Criterion intersectCriterion(Criterion c1, Criterion c2) { - switch (c1.type()) { - case IPV4_SRC: { - IpPrefix ipPrefix = intersectIpPrefix(((IPCriterion) c1).ip(), ((IPCriterion) c2).ip()); - if (ipPrefix == null) { - return null; - } else { - return Criteria.matchIPSrc(ipPrefix); - } - } - case IPV4_DST: { - IpPrefix ipPrefix = intersectIpPrefix(((IPCriterion) c1).ip(), ((IPCriterion) c2).ip()); - if (ipPrefix == null) { - return null; - } else { - return Criteria.matchIPDst(ipPrefix); - } - } - case IPV6_SRC: { - IpPrefix ipPrefix = intersectIpPrefix(((IPCriterion) c1).ip(), ((IPCriterion) c2).ip()); - if (ipPrefix == null) { - return null; - } else { - return Criteria.matchIPv6Src(ipPrefix); - } - } - case IPV6_DST: { - IpPrefix ipPrefix = intersectIpPrefix(((IPCriterion) c1).ip(), ((IPCriterion) c2).ip()); - if (ipPrefix == null) { - return null; - } else { - return Criteria.matchIPv6Dst(ipPrefix); - } - } - default: - if (!c1.equals(c2)) { - return null; - } else { - return c1; - } - } - } - - public static IpPrefix intersectIpPrefix(IpPrefix ip1, IpPrefix ip2) { - if (ip1.contains(ip2)) { - return ip1; - } else if (ip2.contains(ip1)) { - return ip2; - } else { - return null; - } - } - - public static FlowObjectiveCompositionTree parsePolicyString(String policy) { - List<FlowObjectiveCompositionTree> postfix = transformToPostfixForm(policy); - return buildPolicyTree(postfix); - } - - private static List<FlowObjectiveCompositionTree> transformToPostfixForm(String policy) { - Stack<Character> stack = new Stack<>(); - List<FlowObjectiveCompositionTree> postfix = new ArrayList<>(); - - for (int i = 0; i < policy.length(); i++) { - Character ch = policy.charAt(i); - if (Character.isDigit(ch)) { - - int applicationId = ch - '0'; - while (i + 1 < policy.length() && Character.isDigit(policy.charAt(i + 1))) { - i++; - applicationId = applicationId * 10 + policy.charAt(i) - '0'; - } - - postfix.add(new FlowObjectiveCompositionTree((short) applicationId)); - } else if (ch == '(') { - stack.push(ch); - } else if (ch == ')') { - while (stack.peek() != '(') { - postfix.add(new FlowObjectiveCompositionTree(stack.pop())); - } - stack.pop(); - } else { - while (!stack.isEmpty() && compareOperatorPriority(stack.peek(), ch)) { - postfix.add(new FlowObjectiveCompositionTree(stack.pop())); - } - stack.push(ch); - } - } - while (!stack.isEmpty()) { - postfix.add(new FlowObjectiveCompositionTree(stack.pop())); - } - - return postfix; - } - - private static boolean compareOperatorPriority(char peek, char cur) { - if (peek == '/' && (cur == '+' || cur == '>' || cur == '/')) { - return true; - } else if (peek == '>' && (cur == '+' || cur == '>')) { - return true; - } else if (peek == '+' && cur == '+') { - return true; - } - return false; - } - - private static FlowObjectiveCompositionTree buildPolicyTree(List<FlowObjectiveCompositionTree> postfix) { - Stack<FlowObjectiveCompositionTree> stack = new Stack<>(); - for (FlowObjectiveCompositionTree node : postfix) { - if (node.operator == FlowObjectiveCompositionManager.PolicyOperator.Application) { - stack.push(node); - } else { - node.rightChild = stack.pop(); - node.leftChild = stack.pop(); - stack.push(node); - } - } - return stack.pop(); - } - - public static Collection<ForwardingObjective> minusForwardingObjectives(Collection<ForwardingObjective> fo1, - Collection<ForwardingObjective> fo2) { - Map<Integer, ForwardingObjective> map = new HashMap<>(); - for (ForwardingObjective fo : fo1) { - map.put(fo.id(), fo); - } - for (ForwardingObjective fo : fo2) { - map.remove(fo.id()); - } - return map.values(); - } - - -} diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/ForwardTable.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/ForwardTable.java deleted file mode 100644 index 1384bbe2..00000000 --- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/ForwardTable.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2015 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.net.flowobjective.impl.composition; - -import org.onosproject.net.flowobjective.DefaultForwardingObjective; -import org.onosproject.net.flowobjective.ForwardingObjective; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -/** - * Provides a table to store Forward. - */ -public class ForwardTable { - - protected Map<Integer, ForwardingObjective> forwardMap; - protected Map<Integer, List<ForwardingObjective>> generatedParentForwardingObjectiveMap; - - public ForwardTable() { - this.forwardMap = new HashMap<>(); - this.generatedParentForwardingObjectiveMap = new HashMap<>(); - } - - public ForwardUpdateTable updateForward(ForwardingObjective forwardingObjective) { - ForwardUpdateTable updates = new ForwardUpdateTable(); - switch (forwardingObjective.op()) { - case ADD: - this.forwardMap.put(forwardingObjectiveHash(forwardingObjective), forwardingObjective); - this.generatedParentForwardingObjectiveMap - .put(forwardingObjectiveHash(forwardingObjective), new ArrayList<>()); - updates.addObjectives.add(forwardingObjective); - break; - case REMOVE: - if (this.forwardMap.remove(forwardingObjectiveHash(forwardingObjective)) != null) { - updates.removeObjectives.add(forwardingObjective); - } - break; - default: - break; - } - return updates; - } - - public ForwardUpdateTable updateForward(List<ForwardingObjective> forwardingObjectives) { - ForwardUpdateTable updates = new ForwardUpdateTable(); - for (ForwardingObjective forwardingObjective : forwardingObjectives) { - updates.addUpdateTable(this.updateForward(forwardingObjective)); - } - return updates; - } - - public void addGeneratedParentForwardingObjective(ForwardingObjective child, ForwardingObjective parent) { - this.generatedParentForwardingObjectiveMap.get(forwardingObjectiveHash(child)).add(parent); - } - - public void deleteGeneratedParentForwardingObjective(List<ForwardingObjective> children) { - for (ForwardingObjective fo : children) { - this.generatedParentForwardingObjectiveMap.remove(forwardingObjectiveHash(fo)); - } - } - - private List<ForwardingObjective> getGeneratedParentForwardingObjective(ForwardingObjective child) { - return this.generatedParentForwardingObjectiveMap.get(forwardingObjectiveHash(child)); - } - - public List<ForwardingObjective> getGeneratedParentForwardingObjectiveForRemove(ForwardingObjective child) { - List<ForwardingObjective> fos = this.generatedParentForwardingObjectiveMap.get(forwardingObjectiveHash(child)); - List<ForwardingObjective> removeFos = new ArrayList<>(); - for (ForwardingObjective fo : fos) { - removeFos.add(DefaultForwardingObjective.builder() - .fromApp(fo.appId()) - .makePermanent() - .withFlag(fo.flag()) - .withPriority(fo.priority()) - .withSelector(fo.selector()) - .withTreatment(fo.treatment()) - .remove()); - } - return removeFos; - } - - public Collection<ForwardingObjective> getForwardingObjectives() { - return this.forwardMap.values(); - } - - public static int forwardingObjectiveHash(ForwardingObjective forwardingObjective) { - return Objects.hash(forwardingObjective.selector(), forwardingObjective.flag(), - forwardingObjective.permanent(), forwardingObjective.timeout(), - forwardingObjective.appId(), forwardingObjective.priority(), - forwardingObjective.nextId(), forwardingObjective.treatment()); - } -} diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/ForwardUpdateTable.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/ForwardUpdateTable.java deleted file mode 100644 index 9818cfd5..00000000 --- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/ForwardUpdateTable.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2015 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.net.flowobjective.impl.composition; - -import org.onosproject.net.flowobjective.ForwardingObjective; - -import java.util.ArrayList; -import java.util.List; - -/** - * Provides an update table for Forward. - */ -public class ForwardUpdateTable { - public List<ForwardingObjective> addObjectives; - public List<ForwardingObjective> removeObjectives; - - public ForwardUpdateTable() { - this.addObjectives = new ArrayList<>(); - this.removeObjectives = new ArrayList<>(); - } - - public void addUpdateTable(ForwardUpdateTable updateTable) { - this.addObjectives.addAll(updateTable.addObjectives); - this.removeObjectives.addAll(updateTable.removeObjectives); - } - - public List<ForwardingObjective> toForwardingObjectiveList() { - List<ForwardingObjective> forwardingObjectives = new ArrayList<>(); - forwardingObjectives.addAll(this.addObjectives); - forwardingObjectives.addAll(this.removeObjectives); - return forwardingObjectives; - } -} diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/NextTable.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/NextTable.java deleted file mode 100644 index e2787edd..00000000 --- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/NextTable.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2015 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.net.flowobjective.impl.composition; - -import org.onosproject.net.flowobjective.NextObjective; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Provides a table to store Next. - */ -public class NextTable { - - protected Map<Integer, NextObjective> nextMap; - - public NextTable() { - this.nextMap = new HashMap<>(); - } - - public List<NextObjective> updateNext(NextObjective nextObjective) { - List<NextObjective> updates = new ArrayList<>(); - switch (nextObjective.op()) { - case ADD: - this.nextMap.put(nextObjective.id(), nextObjective); - updates.add(nextObjective); - break; - case REMOVE: - this.nextMap.remove(nextObjective.id()); - updates.add(nextObjective); - break; - default: - break; - } - return updates; - } - - public List<NextObjective> updateNext(List<NextObjective> nextObjectives) { - List<NextObjective> updates = new ArrayList<>(); - for (NextObjective nextObjective : nextObjectives) { - updates.addAll(this.updateNext(nextObjective)); - } - return updates; - } - -} diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/package-info.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/package-info.java deleted file mode 100644 index da2a9850..00000000 --- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2015 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. - */ - -/** - * Prototype of a composition mechanism for flow objective composition. - */ -package org.onosproject.net.flowobjective.impl.composition;
\ No newline at end of file diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/package-info.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/package-info.java deleted file mode 100644 index c0779dc2..00000000 --- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2015 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. - */ - -/** - * Implementations of the flow objective programming subsystem. - */ -package org.onosproject.net.flowobjective.impl;
\ No newline at end of file |