blob: 8015f3f1753d1c19ce804cf0e3c2833627eefd50 [file] [log] [blame]
/**
* 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.onrc.onos.of.ctl;
import java.io.IOException;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Future;
import net.onrc.onos.of.ctl.debugcounter.IDebugCounterService;
import net.onrc.onos.of.ctl.debugcounter.IDebugCounterService.CounterException;
import net.onrc.onos.of.ctl.util.OrderedCollection;
import org.jboss.netty.channel.Channel;
import org.projectfloodlight.openflow.protocol.OFActionType;
import org.projectfloodlight.openflow.protocol.OFCapabilities;
import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
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.OFStatsReply;
import org.projectfloodlight.openflow.protocol.OFStatsRequest;
import org.projectfloodlight.openflow.protocol.OFVersion;
import org.projectfloodlight.openflow.types.U64;
public interface IOFSwitch {
/**
* OF1.3 switches should support role-request messages as in the 1.3 spec.
* OF1.0 switches may or may not support the Nicira role request extensions.
* To indicate the support, this property should be set by the associated
* OF1.0 switch driver in the net.onrc.onos.core.drivermanager package.
* The property will be ignored for OF1.3 switches.
*/
public static final String SWITCH_SUPPORTS_NX_ROLE = "supportsNxRole";
//************************
// Channel related
//************************
/**
* Disconnects the switch by closing the TCP connection. Results in a call
* to the channel handler's channelDisconnected method for cleanup
* @throws IOException
*/
public void disconnectSwitch();
/**
* Writes to the OFMessage to the output stream.
*
* @param m
* @param bc
* @throws IOException
*/
public void write(OFMessage m) throws IOException;
/**
* Writes the list of messages to the output stream.
*
* @param msglist
* @param bc
* @throws IOException
*/
public void write(List<OFMessage> msglist) throws IOException;
/**
* Gets the date the switch connected to this controller.
*
* @return the date
*/
public Date getConnectedSince();
/**
* Gets the next available transaction id.
*
* @return the next transaction ID
*/
public int getNextTransactionId();
/**
* Checks if the switch is still connected.
* Only call while holding processMessageLock
*
* @return whether the switch is still disconnected
*/
public boolean isConnected();
/**
* Sets whether the switch is connected.
* Only call while holding modifySwitchLock
*
* @param connected whether the switch is connected
*/
public void setConnected(boolean connected);
/**
* Flushes all flows queued for this switch in the current thread.
* NOTE: The contract is limited to the current thread
*/
public void flush();
/**
* Sets the Netty Channel this switch instance is associated with.
* <p>
* Called immediately after instantiation
*
* @param channel the channel
*/
public void setChannel(Channel channel);
//************************
// Switch features related
//************************
/**
* Gets the datapathId of the switch.
*
* @return the switch buffers
*/
public long getId();
/**
* Gets a string version of the ID for this switch.
*
* @return string version of the ID
*/
public String getStringId();
/**
* Gets the number of buffers.
*
* @return the number of buffers
*/
public int getNumBuffers();
public Set<OFCapabilities> getCapabilities();
public byte getNumTables();
/**
* Returns an OFDescStatsReply message object. Use the methods contained
* to retrieve switch descriptions for Manufacturer, Hw/Sw version etc.
*/
public OFDescStatsReply getSwitchDescription();
/**
* Cancel features reply with a specific transaction ID.
* @param transactionId the transaction ID
*/
public void cancelFeaturesReply(int transactionId);
/**
* Gets the OFActionType set.
* <p>
* getActions has relevance only for an OpenFlow 1.0 switch.
* For OF1.3, each table can support different actions
*
* @return the action set
*/
public Set<OFActionType> getActions();
public void setOFVersion(OFVersion ofv);
public OFVersion getOFVersion();
//************************
// Switch port related
//************************
/**
* the type of change that happened to an open flow port.
*/
public enum PortChangeType {
/** Either a new port has been added by the switch, or we are
* adding a port we just deleted (via a prior notification) due to
* a change in the portNumber-portName mapping.
*/
ADD,
/** some other feature of the port has changed (eg. speed)*/
OTHER_UPDATE,
/** Either a port has been deleted by the switch, or we are deleting
* a port whose portNumber-portName mapping has changed. Note that in
* the latter case, a subsequent notification will be sent out to add a
* port with the new portNumber-portName mapping.
*/
DELETE,
/** Port is up (i.e. enabled). Presumably an earlier notification had
* indicated that it was down. To be UP implies that the port is
* administratively considered UP (see ofp_port_config) AND the port
* link is up AND the port is no longer blocked (see ofp_port_state).
*/
UP,
/** Port is down (i.e. disabled). Presumably an earlier notification had
* indicated that it was up, or the port was always up.
* To be DOWN implies that the port has been either
* administratively brought down (see ofp_port_config) OR the port
* link is down OR the port is blocked (see ofp_port_state).
*/
DOWN,
}
/**
* Describes a change of an open flow port.
*/
public static class PortChangeEvent {
public final OFPortDesc port;
public final PortChangeType type;
/**
* @param port
* @param type
*/
public PortChangeEvent(OFPortDesc port,
PortChangeType type) {
this.port = port;
this.type = type;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((port == null) ? 0 : port.hashCode());
result = prime * result + ((type == null) ? 0 : type.hashCode());
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
PortChangeEvent other = (PortChangeEvent) obj;
if (port == null) {
if (other.port != null) {
return false;
}
} else if (!port.equals(other.port)) {
return false;
}
if (type != other.type) {
return false;
}
return true;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "[" + type + " " + port.toString() + "]";
}
}
/**
* 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
*/
public 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
*/
public Collection<Integer> 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
*/
public OFPortDesc getPort(int 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.
*
* @param portName
* @return port object
*/
public OFPortDesc getPort(String portName);
/**
* Add or modify a switch port. This is called by the core controller
* code in response to a OFPortStatus message.
*
* 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
*/
public OrderedCollection<PortChangeEvent> processOFPortStatus(OFPortStatus ps);
/**
* 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
*/
public Collection<OFPortDesc> getPorts();
/**
* @param portName
* @return Whether a port is enabled per latest port status message
* (not configured down nor link down nor in spanning tree blocking state)
*/
public boolean portEnabled(int portName);
/**
* @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)
*/
public boolean portEnabled(String portName);
/**
* 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
*/
public 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
*/
public OrderedCollection<PortChangeEvent>
setPorts(Collection<OFPortDesc> ports);
//*******************************************
// IOFSwitch object attributes
//************************
/**
* Gets attributes of this switch.
*
* @return attributes of the switch
*/
public Map<Object, Object> getAttributes();
/**
* Checks if a specific switch property exists for this switch.
*
* @param name name of property
* @return value for name
*/
boolean hasAttribute(String name);
/**
* Gets properties for switch specific behavior.
*
* @param name name of property
* @return 'value' for 'name', or null if no entry for 'name' exists
*/
Object getAttribute(String name);
/**
* Sets properties for switch specific behavior.
*
* @param name name of property
* @param value value for name
*/
void setAttribute(String name, Object value);
/**
* Removes properties for switch specific behavior.
*
* @param name name of property
* @return current value for name or null (if not present)
*/
Object removeAttribute(String name);
//************************
// Switch statistics
//************************
/**
* Delivers the statistics future reply.
*
* @param reply the reply to deliver
*/
public void deliverStatisticsReply(OFMessage reply);
/**
* Cancels the statistics reply with the given transaction ID.
*
* @param transactionId the transaction ID
*/
public void cancelStatisticsReply(int transactionId);
/**
* Cancels all statistics replies.
*/
public void cancelAllStatisticsReplies();
/**
* Gets a Future object that can be used to retrieve the asynchronous.
* OFStatisticsReply when it is available.
*
* @param request statistics request
* @return Future object wrapping OFStatisticsReply
* @throws IOException
*/
public Future<List<OFStatsReply>> getStatistics(OFStatsRequest<?> request)
throws IOException;
//************************
// Switch other utilities
//************************
/**
* Clears all flowmods on this switch.
*/
public void clearAllFlowMods();
/**
* Gets the current role of this controller for this IOFSwitch.
*/
public Role getRole();
/**
* Sets this controller's Role for this IOFSwitch to role.
*
* @param role
*/
public void setRole(Role role);
/**
* Gets the next generation ID.
* <p>
* Note: relevant for role request messages in OF1.3
*
* @return next generation ID
*/
public U64 getNextGenerationId();
/**
* Set debug counter service for per-switch counters.
* Called immediately after instantiation.
* @param debugCounters
* @throws CounterException
*/
public void setDebugCounterService(IDebugCounterService debugCounter)
throws CounterException;
/**
* 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 IOException
* @throws SwitchDriverSubHandshakeAlreadyStarted if the sub-handshake has
* already been started
*/
public void startDriverHandshake() throws IOException;
/**
* 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.
*/
public 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.
*/
public void processDriverHandshakeMessage(OFMessage m);
/**
* Set the flow table full flag in the switch.
* XXX S Rethink this for multiple tables
*/
public void setTableFull(boolean isFull);
/**
* Save the features reply for this switch.
*
* @param featuresReply
*/
public void setFeaturesReply(OFFeaturesReply featuresReply);
/**
* Save the portset for this switch.
*
* @param portDescReply
*/
public void setPortDescReply(OFPortDescStatsReply portDescReply);
//************************
// Message handling
//************************
/**
* Handle the message coming from the dataplane.
*
* @param m the actual message
*/
public void handleMessage(OFMessage m);
}