/** * 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.net.SocketAddress; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Date; import org.projectfloodlight.openflow.protocol.OFActionType; import org.projectfloodlight.openflow.protocol.OFCapabilities; import org.projectfloodlight.openflow.protocol.OFControllerRole; import org.projectfloodlight.openflow.protocol.OFFactory; import org.projectfloodlight.openflow.protocol.OFMessage; import org.projectfloodlight.openflow.protocol.OFPortDesc; import org.projectfloodlight.openflow.protocol.OFRequest; import org.projectfloodlight.openflow.protocol.OFStatsReply; import org.projectfloodlight.openflow.protocol.OFStatsRequest; import org.projectfloodlight.openflow.types.DatapathId; import org.projectfloodlight.openflow.types.OFPort; import org.projectfloodlight.openflow.types.TableId; import org.projectfloodlight.openflow.types.U64; import com.google.common.collect.ImmutableList; import com.google.common.util.concurrent.ListenableFuture; import net.floodlightcontroller.core.internal.OFConnection; import net.floodlightcontroller.core.internal.TableFeatures; import net.floodlightcontroller.core.web.serializers.IOFSwitchSerializer; import com.fasterxml.jackson.databind.annotation.JsonSerialize; /** * An openflow switch connecting to the controller. This interface offers * methods for interacting with switches using OpenFlow, and retrieving * information about the switches. */ @JsonSerialize(using=IOFSwitchSerializer.class) public interface IOFSwitch extends IOFMessageWriter { // Attribute keys // These match our YANG schema, make sure they are in sync public static final String SWITCH_DESCRIPTION_FUTURE = "description-future"; public static final String SWITCH_DESCRIPTION_DATA = "description-data"; public static final String SWITCH_SUPPORTS_NX_ROLE = "supports-nx-role"; public static final String PROP_FASTWILDCARDS = "fast-wildcards"; public static final String PROP_REQUIRES_L3_MATCH = "requires-l3-match"; public static final String PROP_SUPPORTS_OFPP_TABLE = "supports-ofpp-table"; public static final String PROP_SUPPORTS_OFPP_FLOOD = "supports-ofpp-flood"; public static final String PROP_SUPPORTS_NETMASK_TBL = "supports-netmask-table"; public static final String PROP_SUPPORTS_BSN_SET_TUNNEL_DST_ACTION = "supports-set-tunnel-dst-action"; public static final String PROP_SUPPORTS_NX_TTL_DECREMENT = "supports-nx-ttl-decrement"; public enum SwitchStatus { /** this switch is in the process of being handshaked. Initial State. */ HANDSHAKE(false), /** the OF channel to this switch is currently in SLAVE role - the switch will not accept * state-mutating messages from this controller node. */ SLAVE(true), /** the OF channel to this switch is currently in MASTER (or EQUALS) role - the switch is * controllable from this controller node. */ MASTER(true), /** the switch has been sorted out and quarantined by the handshake. It does not show up * in normal switch listings */ QUARANTINED(false), /** the switch has disconnected, and will soon be removed from the switch database */ DISCONNECTED(false); private final boolean visible; SwitchStatus(boolean visible) { this.visible = visible; } /** wether this switch is currently visible for normal operation */ public boolean isVisible() { return visible; } /** wether this switch is currently ready to be controlled by this controller */ public boolean isControllable() { return this == MASTER; } } SwitchStatus getStatus(); /** * Returns switch features from features Reply * @return */ long getBuffers(); /** * Disconnect all the switch's channels and mark the switch as disconnected */ void disconnect(); Set<OFActionType> getActions(); Set<OFCapabilities> getCapabilities(); /** * Get the specific TableIds according to the ofp_table_features. * Not all switches have sequential TableIds, so this will give the * specific TableIds used by the switch. * @return */ Collection<TableId> getTables(); /** * @return a copy of the description statistics for this switch */ SwitchDescription getSwitchDescription(); /** * Get the IP address of the remote (switch) end of the connection * @return the inet address */ SocketAddress getInetAddress(); /** * Get list of all enabled ports. This will typically be different from * the list of ports in the OFFeaturesReply, since that one is a static * snapshot of the ports at the time the switch connected to the controller * whereas this port list also reflects the port status messages that have * been received. * @return Unmodifiable list of ports not backed by the underlying collection */ Collection<OFPortDesc> getEnabledPorts(); /** * Get list of the port numbers of all enabled ports. This will typically * be different from the list of ports in the OFFeaturesReply, since that * one is a static snapshot of the ports at the time the switch connected * to the controller whereas this port list also reflects the port status * messages that have been received. * @return Unmodifiable list of ports not backed by the underlying collection */ Collection<OFPort> getEnabledPortNumbers(); /** * Retrieve the port object by the port number. The port object * is the one that reflects the port status updates that have been * received, not the one from the features reply. * @param portNumber * @return port object */ OFPortDesc getPort(OFPort portNumber); /** * Retrieve the port object by the port name. The port object * is the one that reflects the port status updates that have been * received, not the one from the features reply. * Port names are case insentive * @param portName * @return port object */ OFPortDesc getPort(String portName); /** * Get list of all ports. This will typically be different from * the list of ports in the OFFeaturesReply, since that one is a static * snapshot of the ports at the time the switch connected to the controller * whereas this port list also reflects the port status messages that have * been received. * @return Unmodifiable list of ports */ Collection<OFPortDesc> getPorts(); /** * This is mainly for the benefit of the DB code which currently has the * requirement that list elements be sorted by key. Hopefully soon the * DB will handle the sorting automatically or not require it at all, in * which case we could get rid of this method. * @return */ Collection<OFPortDesc> getSortedPorts(); /** * @param portNumber * @return Whether a port is enabled per latest port status message * (not configured down nor link down nor in spanning tree blocking state) */ boolean portEnabled(OFPort portNumber); /** * @param portNumber * @return Whether a port is enabled per latest port status message * (not configured down nor link down nor in spanning tree blocking state) */ boolean portEnabled(String portName); /** * Check is switch is connected * @return Whether or not this switch is connected */ boolean isConnected(); /** * Retrieves the date the switch connected to this controller * @return the date */ Date getConnectedSince(); /** * Get the datapathId of the switch * @return */ DatapathId getId(); /** * Retrieves attributes of this switch * @return */ Map<Object, Object> getAttributes(); /** * Check if the switch is active. I.e., the switch is connected to this * controller and is in master role * @return */ boolean isActive(); /** * Get the current role of the controller for the switch * @return the role of the controller */ OFControllerRole getControllerRole(); /** * Checks if a specific switch property exists for this switch * @param name name of property * @return value for name */ boolean hasAttribute(String name); /** * Set properties for switch specific behavior * @param name name of property * @return value for name */ Object getAttribute(String name); /** * Check if the given attribute is present and if so whether it is equal * to "other" * @param name the name of the attribute to check * @param other the object to compare the attribute against. * @return true iff the specified attribute is set and equals() the given * other object. */ boolean attributeEquals(String name, Object other); /** * Set properties for switch specific behavior * @param name name of property * @param value value for name */ void setAttribute(String name, Object value); /** * Set properties for switch specific behavior * @param name name of property * @return current value for name or null (if not present) */ Object removeAttribute(String name); /** * Returns a factory object that can be used to create OpenFlow messages. * @return */ OFFactory getOFFactory(); /** * Gets the OF connections for this switch instance * @return Collection of IOFConnection */ ImmutableList<IOFConnection> getConnections(); /** * Writes a message to the connection specified by the logical OFMessage category * @param m an OF Message * @param category the category of the OF Message to be sent * @return true upon success; false upon failure */ boolean write(OFMessage m, LogicalOFMessageCategory category); /** * Writes a message list to the connection specified by the logical OFMessage category * @param msglist an OF Message list * @param category the category of the OF Message list to be sent * @return list of failed messages, if any; success denoted by empty list */ Iterable<OFMessage> write(Iterable<OFMessage> msglist, LogicalOFMessageCategory category); /** * Get a connection specified by the logical OFMessage category * @param category the category for the connection the user desires * @return an OF Connection */ OFConnection getConnectionByCategory(LogicalOFMessageCategory category); /** write a Stats (Multipart-) request, register for all corresponding reply messages. * Returns a Future object that can be used to retrieve the List of asynchronous * OFStatsReply messages when it is available. * * @param request stats request * @param category the category for the connection that this request should be written to * @return Future object wrapping OFStatsReply * If the connection is not currently connected, will * return a Future that immediately fails with a @link{SwitchDisconnectedException}. */ <REPLY extends OFStatsReply> ListenableFuture<List<REPLY>> writeStatsRequest(OFStatsRequest<REPLY> request, LogicalOFMessageCategory category); /** write an OpenFlow Request message, register for a single corresponding reply message * or error message. * * @param request * @param categiry the category for the connection that this request should be written to * @return a Future object that can be used to retrieve the asynchrounous * response when available. * * If the connection is not currently connected, will * return a Future that immediately fails with a @link{SwitchDisconnectedException}. */ <R extends OFMessage> ListenableFuture<R> writeRequest(OFRequest<R> request, LogicalOFMessageCategory category); /** * Get the features of a particular switch table. The features are cached from * the initial handshake, or, if applicable, from a more recent * OFTableFeaturesStatsRequest/Reply sent by a user module. * * @param table, The table of which to get features. * @return The table features or null if no features are known for the table requested. */ public TableFeatures getTableFeatures(TableId table); /** * Get the number of tables as returned by the ofp_features_reply. * @return */ short getNumTables(); /** * Get the one-way latency from the switch to the controller. * @return milliseconds */ public U64 getLatency(); }