/** * Copyright 2011, Big Switch Networks, Inc. * Originally created by David Erickson, Stanford University * * 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 net.floodlightcontroller.core; import java.util.Collection; import java.util.List; import org.projectfloodlight.openflow.protocol.OFBsnControllerConnectionsReply; import org.projectfloodlight.openflow.protocol.OFControllerRole; import org.projectfloodlight.openflow.protocol.OFFeaturesReply; import org.projectfloodlight.openflow.protocol.OFMessage; import org.projectfloodlight.openflow.protocol.OFPortDesc; import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply; import org.projectfloodlight.openflow.protocol.OFPortStatus; import org.projectfloodlight.openflow.protocol.OFTableFeaturesStatsReply; import org.projectfloodlight.openflow.types.TableId; import net.floodlightcontroller.util.OrderedCollection; /** * An openflow switch connecting to the controller. This interface offers * methods for interacting with switches using OpenFlow, and retrieving * information about the switches. */ public interface IOFSwitchBackend extends IOFSwitch { /** * Set the netty Channel this switch instance is associated with * Called immediately after instantiation * @param channel */ void registerConnection(IOFConnectionBackend connection); /** * Remove the netty Channels associated with this switch * @param channel */ void removeConnections(); /** * Remove the netty Channel belonging to the specified connection * @param connection */ void removeConnection(IOFConnectionBackend connection); /** * Set the OFFeaturesReply message returned by the switch during initial * handshake. * @param featuresReply */ void setFeaturesReply(OFFeaturesReply featuresReply); /** * Add or modify a switch port. * This is called by the core controller * code in response to a OFPortStatus message. It should not typically be * called by other floodlight applications. * * OFPPR_MODIFY and OFPPR_ADD will be treated as equivalent. The OpenFlow * spec is not clear on whether portNames are portNumbers are considered * authoritative identifiers. We treat portNames <-> portNumber mappings * as fixed. If they change, we delete all previous conflicting ports and * add all new ports. * * @param ps the port status message * @return the ordered Collection of changes "applied" to the old ports * of the switch according to the PortStatus message. A single PortStatus * message can result in multiple changes. * If portName <-> portNumber mappings have * changed, the iteration order ensures that delete events for old * conflicting appear before before events adding new ports */ OrderedCollection<PortChangeEvent> processOFPortStatus(OFPortStatus ps); /** * Add or modify a switch table. * This is called by the core controller code in response to an OFTableFeaturesReply message. * It should not typically be called by other Floodlight modules or applications. * * @param tf, The table features to be updated. */ void processOFTableFeatures(List<OFTableFeaturesStatsReply> replies); /** * Compute the changes that would be required to replace the old ports * of this switch with the new ports * @param ports new ports to set * @return the ordered collection of changes "applied" to the old ports * of the switch in order to set them to the new set. * If portName <-> portNumber mappings have * changed, the iteration order ensures that delete events for old * conflicting appear before before events adding new ports */ OrderedCollection<PortChangeEvent> comparePorts(Collection<OFPortDesc> ports); /** * Replace the ports of this switch with the given ports. * @param ports new ports to set * @return the ordered collection of changes "applied" to the old ports * of the switch in order to set them to the new set. * If portName <-> portNumber mappings have * changed, the iteration order ensures that delete events for old * conflicting appear before before events adding new ports */ OrderedCollection<PortChangeEvent> setPorts(Collection<OFPortDesc> ports); /*********************************************** * The following method can be overridden by * specific types of switches *********************************************** */ /** * Set the SwitchProperties based on it's description * @param description */ void setSwitchProperties(SwitchDescription description); /** * Set the flow table full flag in the switch */ void setTableFull(boolean isFull); /** * Start this switch driver's sub handshake. This might be a no-op but * this method must be called at least once for the switch to be become * ready. * This method must only be called from the I/O thread * @throws SwitchDriverSubHandshakeAlreadyStarted if the sub-handshake has * already been started */ void startDriverHandshake(); /** * Check if the sub-handshake for this switch driver has been completed. * This method can only be called after startDriverHandshake() * * This methods must only be called from the I/O thread * @return true if the sub-handshake has been completed. False otherwise * @throws SwitchDriverSubHandshakeNotStarted if startDriverHandshake() has * not been called yet. */ boolean isDriverHandshakeComplete(); /** * Pass the given OFMessage to the driver as part of this driver's * sub-handshake. Must not be called after the handshake has been completed * This methods must only be called from the I/O thread * @param m The message that the driver should process * @throws SwitchDriverSubHandshakeCompleted if isDriverHandshake() returns * false before this method call * @throws SwitchDriverSubHandshakeNotStarted if startDriverHandshake() has * not been called yet. */ void processDriverHandshakeMessage(OFMessage m); void setPortDescStats(OFPortDescStatsReply portDescStats); /** * Cancel all pending request */ void cancelAllPendingRequests(); /** the the current HA role of this switch */ void setControllerRole(OFControllerRole role); void setStatus(SwitchStatus switchStatus); /** * Updates the switch's mapping of controller connections * @param controllerCxnsReply the controller connections message sent from the switch */ void updateControllerConnections(OFBsnControllerConnectionsReply controllerCxnsReply); /** * Determines whether there is another master controller that the switches are * connected to by looking at the controller connections. * @return true if another viable master exists */ boolean hasAnotherMaster(); /** * In OF1.3+ switches, the table miss behavior is defined by a flow. * We assume the default behavior is to forward to the controller, but * not all tables need that behavior if a limited set of tables are used. * So, we can cap the number of tables we set this flow in to reduce * clutter in API output and to reduce memory consumption on the switch. * * This gets the TableId cap set for this particular switch. * * @return, the highest TableId that should receive a table-miss flow */ TableId getMaxTableForTableMissFlow(); /** * In OF1.3+ switches, the table miss behavior is defined by a flow. * We assume the default behavior is to forward to the controller, but * not all tables need that behavior if a limited set of tables are used. * So, we can cap the number of tables we set this flow in to reduce * clutter in API output and to reduce memory consumption on the switch. * * This sets the TableId cap set for this particular switch. If the max * desired is higher than the number of tables this switch supports, the * max table supported will be used: * * set_max_table = max_supported <= max ? max_supported-1 : max * * @param max, the highest TableId that should receive a table-miss flow * @return the TableId set as the highest */ TableId setMaxTableForTableMissFlow(TableId max); }