package net.floodlightcontroller.flowcache; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Map; 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.core.util.ListenerDispatcher; import net.floodlightcontroller.devicemanager.IDevice; import net.floodlightcontroller.flowcache.IFlowCacheService.FCQueryEvType; import net.floodlightcontroller.flowcache.IFlowReconcileListener; import net.floodlightcontroller.flowcache.OFMatchReconcile; import org.openflow.protocol.OFType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class FlowReconcileManager implements IFloodlightModule, IFlowReconcileService { /** The logger. */ private static Logger logger = LoggerFactory.getLogger(FlowReconcileManager.class); /** * The list of flow reconcile listeners that have registered to get * flow reconcile callbacks. Such callbacks are invoked, for example, when * a switch with existing flow-mods joins this controller and those flows * need to be reconciled with the current configuration of the controller. */ protected ListenerDispatcher<OFType, IFlowReconcileListener> flowReconcileListeners; public OFMatchReconcile newOFMatchReconcile() { return new OFMatchReconcile(); } @Override public synchronized void addFlowReconcileListener(IFlowReconcileListener listener) { flowReconcileListeners.addListener(OFType.FLOW_MOD, listener); if (logger.isDebugEnabled()) { StringBuffer sb = new StringBuffer(); sb.append("FlowReconcileManager FlowMod Listeners: "); for (IFlowReconcileListener l : flowReconcileListeners.getOrderedListeners()) { sb.append(l.getName()); sb.append(","); } logger.debug(sb.toString()); } } @Override public synchronized void removeFlowReconcileListener(IFlowReconcileListener listener) { flowReconcileListeners.removeListener(listener); } @Override public synchronized void clearFlowReconcileListeners() { flowReconcileListeners.clearListeners(); } /** * Reconcile flow. * * @param ofmRcIn the ofm rc in */ public void reconcileFlow(OFMatchReconcile ofmRcIn) { if (logger.isTraceEnabled()) { logger.trace("Reconciliating flow: {}", ofmRcIn.toString()); } ArrayList<OFMatchReconcile> ofmRcList = new ArrayList<OFMatchReconcile>(); ofmRcList.add(ofmRcIn); // Run the flow through all the flow reconcile listeners IFlowReconcileListener.Command retCmd; for (IFlowReconcileListener flowReconciler : flowReconcileListeners.getOrderedListeners()) { if (logger.isTraceEnabled()) { logger.trace("Reconciliatng flow: call listener {}", flowReconciler.getName()); } retCmd = flowReconciler.reconcileFlows(ofmRcList); if (retCmd == IFlowReconcileListener.Command.STOP) { break; } } } @Override public void updateFlowForDestinationDevice(IDevice device, FCQueryEvType fcEvType){ // NO-OP } @Override public void updateFlowForSourceDevice(IDevice device, FCQueryEvType fcEvType){ // NO-OP } @Override public void flowQueryGenericHandler(FlowCacheQueryResp flowResp) { if (flowResp.queryObj.evType != FCQueryEvType.GET) { OFMatchReconcile ofmRc = newOFMatchReconcile(); /* Re-provision these flows */ for (QRFlowCacheObj entry : flowResp.qrFlowCacheObjList) { /* reconcile the flows in entry */ entry.toOFMatchReconcile(ofmRc, flowResp.queryObj.applInstName, OFMatchReconcile.ReconcileAction.UPDATE_PATH); reconcileFlow(ofmRc); } } return; } // IFloodlightModule @Override public Collection<Class<? extends IFloodlightService>> getModuleServices() { Collection<Class<? extends IFloodlightService>> l = new ArrayList<Class<? extends IFloodlightService>>(); l.add(IFlowReconcileService.class); return l; } @Override public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() { Map<Class<? extends IFloodlightService>, IFloodlightService> m = new HashMap<Class<? extends IFloodlightService>, IFloodlightService>(); m.put(IFlowReconcileService.class, this); return m; } @Override public Collection<Class<? extends IFloodlightService>> getModuleDependencies() { return null; } @Override public void init(FloodlightModuleContext context) throws FloodlightModuleException { flowReconcileListeners = new ListenerDispatcher<OFType, IFlowReconcileListener>(); } @Override public void startUp(FloodlightModuleContext context) { } }