package net.floodlightcontroller.routing; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import org.projectfloodlight.openflow.types.DatapathId; import org.projectfloodlight.openflow.types.Masked; import org.projectfloodlight.openflow.types.OFPort; import org.projectfloodlight.openflow.types.U64; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import net.floodlightcontroller.core.module.FloodlightModuleContext; import net.floodlightcontroller.core.module.FloodlightModuleException; import net.floodlightcontroller.core.module.IFloodlightModule; import net.floodlightcontroller.core.module.IFloodlightService; import net.floodlightcontroller.topology.ITopologyManagerBackend; import net.floodlightcontroller.topology.ITopologyService; /** * Separate path-finding and routing functionality from the * topology package. It makes sense to keep much of the core * code in the TopologyInstance, but the TopologyManger is * too confusing implementing so many interfaces and doing * so many tasks. This is a cleaner approach IMHO. * * All routing and path-finding functionality is visible to * the rest of the controller via the IRoutingService implemented * by the RoutingManger (this). The RoutingManger performs * tasks it can perform locally, such as the handling of * IRoutingDecisionChangedListeners, while it defers to the * current TopologyInstance (exposed via the ITopologyManagerBackend * interface) for tasks best performed by the topology * package, such as path-finding. * * @author rizard */ public class RoutingManager implements IFloodlightModule, IRoutingService { private Logger log = LoggerFactory.getLogger(RoutingManager.class); private static ITopologyManagerBackend tm; private List<IRoutingDecisionChangedListener> decisionChangedListeners; @Override public Collection<Class<? extends IFloodlightService>> getModuleServices() { return ImmutableSet.of(IRoutingService.class); } @Override public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() { return ImmutableMap.of(IRoutingService.class, this); } @Override public Collection<Class<? extends IFloodlightService>> getModuleDependencies() { return ImmutableSet.of(ITopologyService.class); } @Override public void init(FloodlightModuleContext context) throws FloodlightModuleException { log.debug("RoutingManager starting up"); tm = (ITopologyManagerBackend) context.getServiceImpl(ITopologyService.class); decisionChangedListeners = new ArrayList<IRoutingDecisionChangedListener>(); } @Override public void startUp(FloodlightModuleContext context) throws FloodlightModuleException { } @Override public void setPathMetric(PATH_METRIC metric) { tm.setPathMetric(metric); } @Override public PATH_METRIC getPathMetric() { return tm.getPathMetric(); } @Override public void setMaxPathsToCompute(int max) { tm.setMaxPathsToCompute(max); } @Override public int getMaxPathsToCompute() { return tm.getMaxPathsToCompute(); } @Override public Path getPath(DatapathId src, DatapathId dst) { return tm.getCurrentTopologyInstance().getPath(src, dst); } @Override public Path getPath(DatapathId src, OFPort srcPort, DatapathId dst, OFPort dstPort) { return tm.getCurrentTopologyInstance().getPath(src, srcPort, dst, dstPort); } @Override public List<Path> getPathsFast(DatapathId src, DatapathId dst) { return tm.getCurrentTopologyInstance().getPathsFast(src, dst, tm.getMaxPathsToCompute()); } @Override public List<Path> getPathsFast(DatapathId src, DatapathId dst, int numReqPaths) { return tm.getCurrentTopologyInstance().getPathsFast(src, dst, numReqPaths); } @Override public List<Path> getPathsSlow(DatapathId src, DatapathId dst, int numReqPaths) { return tm.getCurrentTopologyInstance().getPathsSlow(src, dst, numReqPaths); } @Override public boolean pathExists(DatapathId src, DatapathId dst) { return tm.getCurrentTopologyInstance().pathExists(src, dst); } @Override public boolean forceRecompute() { return tm.forceRecompute(); } /** * Registers an IRoutingDecisionChangedListener. * * @param listener * @return */ @Override public void addRoutingDecisionChangedListener(IRoutingDecisionChangedListener listener) { decisionChangedListeners.add(listener); } /** * Deletes an IRoutingDecisionChangedListener. * * @param listener * @return */ @Override public void removeRoutingDecisionChangedListener(IRoutingDecisionChangedListener listener) { decisionChangedListeners.remove(listener); } /** * Listens for the event to the IRoutingDecisionChanged listener and calls routingDecisionChanged(). * * @param changedDecisions * @return */ @Override public void handleRoutingDecisionChange(Iterable<Masked<U64>> changedDecisions) { for (IRoutingDecisionChangedListener listener : decisionChangedListeners) { listener.routingDecisionChanged(changedDecisions); } } }