Toggle navigation
Toggle navigation
This project
Loading...
Sign in
홍길동
/
onos
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Snippets
Network
Create a new issue
Builds
Commits
Issue Boards
Authored by
alshabib
2014-09-02 19:00:32 -0700
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
6171f180351da3de58a47880785bc6e01fc60f48
6171f180
1 parent
6e746f31
refactored OF switch into driver and frontend
Show whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
755 additions
and
361 deletions
of/api/src/main/java/org/onlab/onos/of/controller/OpenFlowSwitch.java
of/api/src/main/java/org/onlab/onos/of/controller/RoleState.java
of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/AbstractOpenFlowSwitch.java → of/api/src/main/java/org/onlab/onos/of/controller/driver/AbstractOpenFlowSwitch.java
of/api/src/main/java/org/onlab/onos/of/controller/driver/OpenFlowAgent.java
of/api/src/main/java/org/onlab/onos/of/controller/driver/OpenFlowSwitchDriver.java
of/api/src/main/java/org/onlab/onos/of/controller/driver/OpenFlowSwitchDriverFactory.java
of/api/src/main/java/org/onlab/onos/of/controller/driver/RoleHandler.java
of/api/src/main/java/org/onlab/onos/of/controller/driver/RoleRecvStatus.java
of/api/src/main/java/org/onlab/onos/of/controller/driver/RoleReplyInfo.java
of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/SwitchDriverSubHandshakeAlreadyStarted.java → of/api/src/main/java/org/onlab/onos/of/controller/driver/SwitchDriverSubHandshakeAlreadyStarted.java
of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/SwitchDriverSubHandshakeCompleted.java → of/api/src/main/java/org/onlab/onos/of/controller/driver/SwitchDriverSubHandshakeCompleted.java
of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/SwitchDriverSubHandshakeException.java → of/api/src/main/java/org/onlab/onos/of/controller/driver/SwitchDriverSubHandshakeException.java
of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/SwitchDriverSubHandshakeNotStarted.java → of/api/src/main/java/org/onlab/onos/of/controller/driver/SwitchDriverSubHandshakeNotStarted.java
of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/SwitchDriverSubHandshakeStateException.java → of/api/src/main/java/org/onlab/onos/of/controller/driver/SwitchDriverSubHandshakeStateException.java
of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/SwitchStateException.java → of/api/src/main/java/org/onlab/onos/of/controller/driver/SwitchStateException.java
of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/Controller.java
of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/IOFSwitchManager.java
of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/OFChannelHandler.java
of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/OpenFlowControllerImpl.java
of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/RoleManager.java
of/ctl/src/main/java/org/onlab/onos/of/drivers/DriverManager.java
of/ctl/src/main/java/org/onlab/onos/of/drivers/OFSwitchImplCPqD13.java
of/ctl/src/main/java/org/onlab/onos/of/drivers/OFSwitchImplOVS10.java
of/ctl/src/main/java/org/onlab/onos/of/drivers/OFSwitchImplOVS13.java
of/api/src/main/java/org/onlab/onos/of/controller/OpenFlowSwitch.java
View file @
6171f18
package
org
.
onlab
.
onos
.
of
.
controller
;
import
java.util.List
;
import
org.projectfloodlight.openflow.protocol.OFFactory
;
import
org.projectfloodlight.openflow.protocol.OFMessage
;
import
org.projectfloodlight.openflow.protocol.OFPortDesc
;
/**
* Abstract model of an OpenFlow Switch.
*
* Represents to provider facing side of a switch.
*/
public
interface
OpenFlowSwitch
{
/**
* Writes the message to th
is switch
.
* Writes the message to th
e driver
.
*
* @param msg the message to write
*/
public
void
sendMsg
(
OFMessage
msg
);
/**
* Writes to the OFMessage list to the driver.
*
* @param msgs the messages to be written
*/
public
void
sendMsg
(
List
<
OFMessage
>
msgs
);
/**
* Handle a message from the switch.
* @param fromSwitch the message to handle
*/
public
void
handleMessage
(
OFMessage
fromSwitch
);
/**
* Sets the role for this switch.
* @param role the role to set.
*/
public
void
setRole
(
RoleState
role
);
/**
* Fetch the role for this switch.
* @return the role.
*/
public
RoleState
getRole
();
/**
* Fetches the ports of this switch.
* @return unmodifiable list of the ports.
*/
public
List
<
OFPortDesc
>
getPorts
();
/**
* Provides the factory for this OF version.
* @return OF version specific factory.
*/
public
OFFactory
factory
();
/**
* Gets a string version of the ID for this switch.
*
* @return string version of the ID
*/
public
String
getStringId
();
/**
* Gets the datapathId of the switch.
*
* @return the switch dpid in long format
*/
public
long
getId
();
/**
* Disconnects the switch by closing the TCP connection. Results in a call
* to the channel handler's channelDisconnected method for cleanup
*/
public
void
disconnectSwitch
();
}
...
...
of/api/src/main/java/org/onlab/onos/of/controller/RoleState.java
View file @
6171f18
...
...
@@ -21,3 +21,5 @@ public enum RoleState {
}
...
...
of/
ctl/src/main/java/org/onlab/onos/of/controller/impl/internal
/AbstractOpenFlowSwitch.java
→
of/
api/src/main/java/org/onlab/onos/of/controller/driver
/AbstractOpenFlowSwitch.java
View file @
6171f18
...
...
@@ -15,7 +15,7 @@
* under the License.
**/
package
org
.
onlab
.
onos
.
of
.
controller
.
impl
.
internal
;
package
org
.
onlab
.
onos
.
of
.
controller
.
driver
;
import
java.io.IOException
;
import
java.util.Collections
;
...
...
@@ -24,11 +24,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import
org.jboss.netty.channel.Channel
;
import
org.onlab.onos.of.controller.Dpid
;
import
org.onlab.onos.of.controller.OpenFlowSwitch
;
import
org.onlab.onos.of.controller.RoleState
;
import
org.onlab.onos.of.controller.impl.internal.OpenFlowControllerImpl.OpenFlowSwitchAgent
;
import
org.onlab.onos.of.controller.impl.internal.RoleManager.RoleRecvStatus
;
import
org.onlab.onos.of.controller.impl.internal.RoleManager.RoleReplyInfo
;
import
org.projectfloodlight.openflow.protocol.OFDescStatsReply
;
import
org.projectfloodlight.openflow.protocol.OFErrorMsg
;
import
org.projectfloodlight.openflow.protocol.OFExperimenter
;
...
...
@@ -43,19 +39,22 @@ import org.projectfloodlight.openflow.protocol.OFVersion;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
public
abstract
class
AbstractOpenFlowSwitch
implements
OpenFlowSwitch
{
/**
* An abstract representation of an OpenFlow switch. Can be extended by others
* to serve as a base for their vendor specific representation of a switch.
*/
public
abstract
class
AbstractOpenFlowSwitch
implements
OpenFlowSwitchDriver
{
private
static
Logger
log
=
LoggerFactory
.
getLogger
(
AbstractOpenFlowSwitch
.
class
);
protected
Channel
channel
;
protected
boolean
startDriverHandshakeCalled
=
false
;
private
boolean
connected
;
private
Dpid
dpid
;
private
OpenFlowSwitchAgent
agent
;
private
AtomicInteger
xidCounter
=
new
AtomicInteger
(
0
);
protected
boolean
startDriverHandshakeCalled
=
false
;
private
final
Dpid
dpid
;
private
OpenFlowAgent
agent
;
private
final
AtomicInteger
xidCounter
=
new
AtomicInteger
(
0
);
private
OFVersion
ofVersion
;
...
...
@@ -63,12 +62,17 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch {
protected
boolean
tableFull
;
private
final
RoleManager
roleMan
=
new
RoleManager
(
this
)
;
private
RoleHandler
roleMan
;
protected
RoleState
role
;
protected
OFFeaturesReply
features
;
protected
OFDescStatsReply
desc
;
/**
* Given a dpid build this switch.
* @param dp the dpid
*/
protected
AbstractOpenFlowSwitch
(
Dpid
dp
)
{
this
.
dpid
=
dp
;
}
...
...
@@ -77,59 +81,38 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch {
// 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
*/
@Override
public
final
void
disconnectSwitch
()
{
this
.
channel
.
close
();
}
/**
* Writes to the OFMessage to the output stream.
*
* @param m the message to be written
*/
public
abstract
void
sendMsg
(
OFMessage
m
);
@Override
public
final
void
sendMsg
(
OFMessage
m
)
{
this
.
write
(
m
);
}
/**
* Writes to the OFMessage list to the output stream.
*
* @param msgs the messages to be written
*/
public
void
write
(
List
<
OFMessage
>
msgs
)
{
this
.
channel
.
write
(
msgs
);
@Override
public
final
void
sendMsg
(
List
<
OFMessage
>
msgs
)
{
this
.
write
(
msgs
);
}
@Override
public
abstract
void
write
(
OFMessage
msg
);
/**
* Checks if the switch is still connected.
* Only call while holding processMessageLock
*
* @return whether the switch is still disconnected
*/
@Override
public
abstract
void
write
(
List
<
OFMessage
>
msgs
);
@Override
public
final
boolean
isConnected
()
{
return
this
.
connected
;
}
/**
* Sets whether the switch is connected.
* Only call while holding modifySwitchLock
*
* @param connected whether the switch is connected
*/
final
void
setConnected
(
boolean
connected
)
{
@Override
public
final
void
setConnected
(
boolean
connected
)
{
this
.
connected
=
connected
;
};
/**
* Sets the Netty Channel this switch instance is associated with.
* <p>
* Called immediately after instantiation
*
* @param channel the channel
*/
@Override
public
final
void
setChannel
(
Channel
channel
)
{
this
.
channel
=
channel
;
};
...
...
@@ -138,41 +121,32 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch {
// Switch features related
//************************
/**
* Gets the datapathId of the switch.
*
* @return the switch buffers
*/
@Override
public
final
long
getId
()
{
return
this
.
dpid
.
value
();
};
/**
* Gets a string version of the ID for this switch.
*
* @return string version of the ID
*/
@Override
public
final
String
getStringId
()
{
return
this
.
dpid
.
toString
();
}
@Override
public
final
void
setOFVersion
(
OFVersion
ofV
)
{
this
.
ofVersion
=
ofV
;
}
void
setTableFull
(
boolean
full
)
{
@Override
public
void
setTableFull
(
boolean
full
)
{
this
.
tableFull
=
full
;
}
@Override
public
void
setFeaturesReply
(
OFFeaturesReply
featuresReply
)
{
this
.
features
=
featuresReply
;
}
/**
* Let peoeple know if you support Nicira style role requests.
*
* @return support Nicira roles or not.
*/
@Override
public
abstract
Boolean
supportNxRole
();
//************************
...
...
@@ -183,52 +157,66 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch {
*
* @param m the actual message
*/
@Override
public
final
void
handleMessage
(
OFMessage
m
)
{
this
.
agent
.
processMessage
(
m
);
}
@Override
public
RoleState
getRole
()
{
return
role
;
};
final
boolean
addConnectedSwitch
()
{
return
this
.
agent
.
addConnectedSwitch
(
this
.
getId
(),
this
);
@Override
public
final
boolean
connectSwitch
()
{
return
this
.
agent
.
addConnectedSwitch
(
dpid
,
this
);
}
final
boolean
addActivatedMasterSwitch
()
{
return
this
.
agent
.
addActivatedMasterSwitch
(
this
.
getId
(),
this
);
@Override
public
final
boolean
activateMasterSwitch
()
{
return
this
.
agent
.
addActivatedMasterSwitch
(
dpid
,
this
);
}
final
boolean
addActivatedEqualSwitch
()
{
return
this
.
agent
.
addActivatedEqualSwitch
(
this
.
getId
(),
this
);
@Override
public
final
boolean
activateEqualSwitch
()
{
return
this
.
agent
.
addActivatedEqualSwitch
(
dpid
,
this
);
}
final
void
transitionToEqualSwitch
()
{
this
.
agent
.
transitionToEqualSwitch
(
this
.
getId
());
@Override
public
final
void
transitionToEqualSwitch
()
{
this
.
agent
.
transitionToEqualSwitch
(
dpid
);
}
final
void
transitionToMasterSwitch
()
{
this
.
agent
.
transitionToMasterSwitch
(
this
.
getId
());
@Override
public
final
void
transitionToMasterSwitch
()
{
this
.
agent
.
transitionToMasterSwitch
(
dpid
);
}
final
void
removeConnectedSwitch
()
{
this
.
agent
.
removeConnectedSwitch
(
this
.
getId
());
@Override
public
final
void
removeConnectedSwitch
()
{
this
.
agent
.
removeConnectedSwitch
(
dpid
);
}
protected
OFFactory
factory
()
{
@Override
public
OFFactory
factory
()
{
return
OFFactories
.
getFactory
(
ofVersion
);
}
@Override
public
void
setPortDescReply
(
OFPortDescStatsReply
portDescReply
)
{
this
.
ports
=
portDescReply
;
}
@Override
public
abstract
void
startDriverHandshake
();
@Override
public
abstract
boolean
isDriverHandshakeComplete
();
@Override
public
abstract
void
processDriverHandshakeMessage
(
OFMessage
m
);
@Override
public
void
setRole
(
RoleState
role
)
{
try
{
if
(
this
.
roleMan
.
sendRoleRequest
(
role
,
RoleRecvStatus
.
MATCHED_SET_ROLE
))
{
...
...
@@ -241,7 +229,8 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch {
// Role Handling
void
handleRole
(
OFMessage
m
)
throws
SwitchStateException
{
@Override
public
void
handleRole
(
OFMessage
m
)
throws
SwitchStateException
{
RoleReplyInfo
rri
=
roleMan
.
extractOFRoleReply
((
OFRoleReply
)
m
);
RoleRecvStatus
rrs
=
roleMan
.
deliverRoleReply
(
rri
);
if
(
rrs
==
RoleRecvStatus
.
MATCHED_SET_ROLE
)
{
...
...
@@ -254,7 +243,8 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch {
}
}
void
handleNiciraRole
(
OFMessage
m
)
throws
SwitchStateException
{
@Override
public
void
handleNiciraRole
(
OFMessage
m
)
throws
SwitchStateException
{
RoleState
r
=
this
.
roleMan
.
extractNiciraRoleReply
((
OFExperimenter
)
m
);
if
(
r
==
null
)
{
// The message wasn't really a Nicira role reply. We just
...
...
@@ -274,7 +264,8 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch {
}
}
boolean
handleRoleError
(
OFErrorMsg
error
)
{
@Override
public
boolean
handleRoleError
(
OFErrorMsg
error
)
{
try
{
return
RoleRecvStatus
.
OTHER_EXPECTATION
!=
this
.
roleMan
.
deliverError
(
error
);
}
catch
(
SwitchStateException
e
)
{
...
...
@@ -283,25 +274,39 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch {
return
true
;
}
void
reassertRole
()
{
@Override
public
void
reassertRole
()
{
if
(
this
.
getRole
()
==
RoleState
.
MASTER
)
{
this
.
setRole
(
RoleState
.
MASTER
);
}
}
void
setAgent
(
OpenFlowSwitchAgent
ag
)
{
@Override
public
final
void
setAgent
(
OpenFlowAgent
ag
)
{
if
(
this
.
agent
==
null
)
{
this
.
agent
=
ag
;
}
}
@Override
public
final
void
setRoleHandler
(
RoleHandler
roleHandler
)
{
if
(
this
.
roleMan
==
null
)
{
this
.
roleMan
=
roleHandler
;
}
}
public
void
setSwitchDescription
(
OFDescStatsReply
desc
)
{
// TODO Auto-generated method stub
@Override
public
void
setSwitchDescription
(
OFDescStatsReply
d
)
{
this
.
desc
=
d
;
}
protected
int
getNextTransactionId
()
{
@Override
public
int
getNextTransactionId
()
{
return
this
.
xidCounter
.
getAndIncrement
();
}
protected
List
<
OFPortDesc
>
getPorts
()
{
@Override
public
List
<
OFPortDesc
>
getPorts
()
{
return
Collections
.
unmodifiableList
(
ports
.
getEntries
());
}
...
...
of/api/src/main/java/org/onlab/onos/of/controller/driver/OpenFlowAgent.java
0 → 100644
View file @
6171f18
package
org
.
onlab
.
onos
.
of
.
controller
.
driver
;
import
org.onlab.onos.of.controller.Dpid
;
import
org.onlab.onos.of.controller.OpenFlowSwitch
;
import
org.projectfloodlight.openflow.protocol.OFMessage
;
/**
* Responsible for keeping track of the current set of switches
* connected to the system. As well as whether they are in Master
* role or not.
*
*/
public
interface
OpenFlowAgent
{
/**
* Add a switch that has just connected to the system.
* @param dpid the dpid to add
* @param sw the actual switch object.
* @return true if added, false otherwise.
*/
public
boolean
addConnectedSwitch
(
Dpid
dpid
,
OpenFlowSwitch
sw
);
/**
* Checks if the activation for this switch is valid.
* @param dpid the dpid to check
* @return true if valid, false otherwise
*/
public
boolean
validActivation
(
Dpid
dpid
);
/**
* Called when a switch is activated, with this controller's role as MASTER.
* @param dpid the dpid to add.
* @param sw the actual switch
* @return true if added, false otherwise.
*/
public
boolean
addActivatedMasterSwitch
(
Dpid
dpid
,
OpenFlowSwitch
sw
);
/**
* Called when a switch is activated, with this controller's role as EQUAL.
* @param dpid the dpid to add.
* @param sw the actual switch
* @return true if added, false otherwise.
*/
public
boolean
addActivatedEqualSwitch
(
Dpid
dpid
,
OpenFlowSwitch
sw
);
/**
* Called when this controller's role for a switch transitions from equal
* to master. For 1.0 switches, we internally refer to the role 'slave' as
* 'equal' - so this transition is equivalent to 'addActivatedMasterSwitch'.
* @param dpid the dpid to transistion.
*/
public
void
transitionToMasterSwitch
(
Dpid
dpid
);
/**
* Called when this controller's role for a switch transitions to equal.
* For 1.0 switches, we internally refer to the role 'slave' as
* 'equal'.
* @param dpid the dpid to transistion.
*/
public
void
transitionToEqualSwitch
(
Dpid
dpid
);
/**
* Clear all state in controller switch maps for a switch that has
* disconnected from the local controller. Also release control for
* that switch from the global repository. Notify switch listeners.
* @param dpid the dpid to remove.
*/
public
void
removeConnectedSwitch
(
Dpid
dpid
);
/**
* Process a message coming from a switch.
* @param m the message to process
*/
public
void
processMessage
(
OFMessage
m
);
}
of/api/src/main/java/org/onlab/onos/of/controller/driver/OpenFlowSwitchDriver.java
0 → 100644
View file @
6171f18
package
org
.
onlab
.
onos
.
of
.
controller
.
driver
;
import
java.util.List
;
import
org.jboss.netty.channel.Channel
;
import
org.onlab.onos.of.controller.OpenFlowSwitch
;
import
org.projectfloodlight.openflow.protocol.OFDescStatsReply
;
import
org.projectfloodlight.openflow.protocol.OFErrorMsg
;
import
org.projectfloodlight.openflow.protocol.OFFeaturesReply
;
import
org.projectfloodlight.openflow.protocol.OFMessage
;
import
org.projectfloodlight.openflow.protocol.OFPortDescStatsReply
;
import
org.projectfloodlight.openflow.protocol.OFVersion
;
/**
* Represents the driver side of an OpenFlow switch.
* This interface should never be exposed to consumers.
*
*/
public
interface
OpenFlowSwitchDriver
extends
OpenFlowSwitch
{
/**
* Sets the OpenFlow agent to be used. This method
* can only be called once.
* @param agent the agent to set.
*/
public
void
setAgent
(
OpenFlowAgent
agent
);
/**
* Sets the Role handler object.
* This method can only be called once.
* @param roleHandler the roleHandler class
*/
public
void
setRoleHandler
(
RoleHandler
roleHandler
);
/**
* Reasserts this controllers role to the switch.
* Useful in cases where the switch no longer agrees
* that this controller has the role it claims.
*/
public
void
reassertRole
();
/**
* Handle the situation where the role request triggers an error.
* @param error the error to handle.
* @return true if handled, false if not.
*/
public
boolean
handleRoleError
(
OFErrorMsg
error
);
/**
* If this driver know of Nicira style role messages, these should
* be handled here.
* @param m the role message to handle.
* @throws SwitchStateException if the message received was
* not a nicira role or was malformed.
*/
public
void
handleNiciraRole
(
OFMessage
m
)
throws
SwitchStateException
;
/**
* Handle OF 1.x (where x > 0) role messages.
* @param m the role message to handle
* @throws SwitchStateException if the message received was
* not a nicira role or was malformed.
*/
public
void
handleRole
(
OFMessage
m
)
throws
SwitchStateException
;
/**
* Starts the driver specific handshake process.
*/
public
void
startDriverHandshake
();
/**
* Checks whether the driver specific handshake is complete.
* @return true is finished, false if not.
*/
public
boolean
isDriverHandshakeComplete
();
/**
* Process a message during the driver specific handshake.
* @param m the message to process.
*/
public
void
processDriverHandshakeMessage
(
OFMessage
m
);
/**
* Announce to the OpenFlow agent that this switch has connected.
* @return true if successful, false if duplicate switch.
*/
public
boolean
connectSwitch
();
/**
* Activate this MASTER switch-controller relationship in the OF agent.
* @return true is successful, false is switch has not
* connected or is unknown to the system.
*/
public
boolean
activateMasterSwitch
();
/**
* Activate this EQUAL switch-controller relationship in the OF agent.
* @return true is successful, false is switch has not
* connected or is unknown to the system.
*/
public
boolean
activateEqualSwitch
();
/**
* Transition this switch-controller relationship to an EQUAL state.
*/
public
void
transitionToEqualSwitch
();
/**
* Transition this switch-controller relationship to an Master state.
*/
public
void
transitionToMasterSwitch
();
/**
* Remove this switch from the openflow agent.
*/
public
void
removeConnectedSwitch
();
/**
* Sets the ports on this switch.
* @param portDescReply the port set and descriptions
*/
public
void
setPortDescReply
(
OFPortDescStatsReply
portDescReply
);
/**
* Sets the features reply for this switch.
* @param featuresReply the features to set.
*/
public
void
setFeaturesReply
(
OFFeaturesReply
featuresReply
);
/**
* Sets the switch description.
* @param desc the descriptions
*/
public
void
setSwitchDescription
(
OFDescStatsReply
desc
);
/**
* Gets the next transaction id to use.
* @return the xid
*/
public
int
getNextTransactionId
();
/**
* Does this switch support Nicira Role messages.
* @return true if supports, false otherwise.
*/
public
Boolean
supportNxRole
();
/**
* Sets the OF version for this switch.
* @param ofV the version to set.
*/
public
void
setOFVersion
(
OFVersion
ofV
);
/**
* Sets this switch has having a full flowtable.
* @param full true if full, false otherswise.
*/
public
void
setTableFull
(
boolean
full
);
/**
* Sets the associated Netty channel for this switch.
* @param channel the Netty channel
*/
public
void
setChannel
(
Channel
channel
);
/**
* Sets whether the switch is connected.
*
* @param connected whether the switch is connected
*/
public
void
setConnected
(
boolean
connected
);
/**
* Checks if the switch is still connected.
*
* @return whether the switch is still connected
*/
public
boolean
isConnected
();
/**
* Writes the message to the output stream
* in a driver specific manner.
*
* @param msg the message to write
*/
public
void
write
(
OFMessage
msg
);
/**
* Writes to the OFMessage list to the output stream
* in a driver specific manner.
*
* @param msgs the messages to be written
*/
public
void
write
(
List
<
OFMessage
>
msgs
);
}
of/api/src/main/java/org/onlab/onos/of/controller/driver/OpenFlowSwitchDriverFactory.java
0 → 100644
View file @
6171f18
package
org
.
onlab
.
onos
.
of
.
controller
.
driver
;
import
org.onlab.onos.of.controller.Dpid
;
import
org.projectfloodlight.openflow.protocol.OFDescStatsReply
;
import
org.projectfloodlight.openflow.protocol.OFVersion
;
/**
* Switch factory which returns concrete switch objects for the
* physical openflow switch in use.
*
*/
public
interface
OpenFlowSwitchDriverFactory
{
/**
* Constructs the real openflow switch representation.
* @param dpid the dpid for this switch.
* @param desc its description.
* @param ofv the OF version in use
* @return the openflow switch representation.
*/
public
OpenFlowSwitchDriver
getOFSwitchImpl
(
Dpid
dpid
,
OFDescStatsReply
desc
,
OFVersion
ofv
);
}
of/api/src/main/java/org/onlab/onos/of/controller/driver/RoleHandler.java
0 → 100644
View file @
6171f18
package
org
.
onlab
.
onos
.
of
.
controller
.
driver
;
import
java.io.IOException
;
import
org.onlab.onos.of.controller.RoleState
;
import
org.projectfloodlight.openflow.protocol.OFErrorMsg
;
import
org.projectfloodlight.openflow.protocol.OFExperimenter
;
import
org.projectfloodlight.openflow.protocol.OFRoleReply
;
/**
* Role handling.
*
*/
public
interface
RoleHandler
{
/**
* Extract the role from an OFVendor message.
*
* Extract the role from an OFVendor message if the message is a
* Nicira role reply. Otherwise return null.
*
* @param experimenterMsg The vendor message to parse.
* @return The role in the message if the message is a Nicira role
* reply, null otherwise.
* @throws SwitchStateException If the message is a Nicira role reply
* but the numeric role value is unknown.
*/
public
RoleState
extractNiciraRoleReply
(
OFExperimenter
experimenterMsg
)
throws
SwitchStateException
;
/**
* Send a role request with the given role to the switch and update
* the pending request and timestamp.
* Sends an OFPT_ROLE_REQUEST to an OF1.3 switch, OR
* Sends an NX_ROLE_REQUEST to an OF1.0 switch if configured to support it
* in the IOFSwitch driver. If not supported, this method sends nothing
* and returns 'false'. The caller should take appropriate action.
*
* One other optimization we do here is that for OF1.0 switches with
* Nicira role message support, we force the Role.EQUAL to become
* Role.SLAVE, as there is no defined behavior for the Nicira role OTHER.
* We cannot expect it to behave like SLAVE. We don't have this problem with
* OF1.3 switches, because Role.EQUAL is well defined and we can simulate
* SLAVE behavior by using ASYNC messages.
*
* @param role
* @throws IOException
* @returns false if and only if the switch does not support role-request
* messages, according to the switch driver; true otherwise.
*/
public
boolean
sendRoleRequest
(
RoleState
role
,
RoleRecvStatus
exp
)
throws
IOException
;
/**
* Extract the role information from an OF1.3 Role Reply Message.
* @param h
* @param rrmsg
* @return RoleReplyInfo object
* @throws SwitchStateException
*/
public
RoleReplyInfo
extractOFRoleReply
(
OFRoleReply
rrmsg
)
throws
SwitchStateException
;
/**
* Deliver a received role reply.
*
* Check if a request is pending and if the received reply matches the
* the expected pending reply (we check both role and xid) we set
* the role for the switch/channel.
*
* If a request is pending but doesn't match the reply we ignore it, and
* return
*
* If no request is pending we disconnect with a SwitchStateException
*
* @param rri information about role-reply in format that
* controller can understand.
* @throws SwitchStateException if no request is pending
*/
public
RoleRecvStatus
deliverRoleReply
(
RoleReplyInfo
rri
)
throws
SwitchStateException
;
/**
* Called if we receive an error message. If the xid matches the
* pending request we handle it otherwise we ignore it.
*
* Note: since we only keep the last pending request we might get
* error messages for earlier role requests that we won't be able
* to handle
*/
public
RoleRecvStatus
deliverError
(
OFErrorMsg
error
)
throws
SwitchStateException
;
}
of/api/src/main/java/org/onlab/onos/of/controller/driver/RoleRecvStatus.java
0 → 100644
View file @
6171f18
package
org
.
onlab
.
onos
.
of
.
controller
.
driver
;
/**
* When we remove a pending role request we use this enum to indicate how we
* arrived at the decision. When we send a role request to the switch, we
* also use this enum to indicate what we expect back from the switch, so the
* role changer can match the reply to our expectation.
*/
public
enum
RoleRecvStatus
{
/** The switch returned an error indicating that roles are not.
* supported*/
UNSUPPORTED
,
/** The request timed out. */
NO_REPLY
,
/** The reply was old, there is a newer request pending. */
OLD_REPLY
,
/**
* The reply's role matched the role that this controller set in the
* request message - invoked either initially at startup or to reassert
* current role.
*/
MATCHED_CURRENT_ROLE
,
/**
* The reply's role matched the role that this controller set in the
* request message - this is the result of a callback from the
* global registry, followed by a role request sent to the switch.
*/
MATCHED_SET_ROLE
,
/**
* The reply's role was a response to the query made by this controller.
*/
REPLY_QUERY
,
/** We received a role reply message from the switch
* but the expectation was unclear, or there was no expectation.
*/
OTHER_EXPECTATION
,
}
of/api/src/main/java/org/onlab/onos/of/controller/driver/RoleReplyInfo.java
0 → 100644
View file @
6171f18
package
org
.
onlab
.
onos
.
of
.
controller
.
driver
;
import
org.onlab.onos.of.controller.RoleState
;
import
org.projectfloodlight.openflow.types.U64
;
/**
* Helper class returns role reply information in the format understood
* by the controller.
*/
public
class
RoleReplyInfo
{
private
final
RoleState
role
;
private
final
U64
genId
;
private
final
long
xid
;
public
RoleReplyInfo
(
RoleState
role
,
U64
genId
,
long
xid
)
{
this
.
role
=
role
;
this
.
genId
=
genId
;
this
.
xid
=
xid
;
}
public
RoleState
getRole
()
{
return
role
;
}
public
U64
getGenId
()
{
return
genId
;
}
public
long
getXid
()
{
return
xid
;
}
@Override
public
String
toString
()
{
return
"[Role:"
+
role
+
" GenId:"
+
genId
+
" Xid:"
+
xid
+
"]"
;
}
}
of/
ctl/src/main/java/org/onlab/onos/of/controller/impl/internal
/SwitchDriverSubHandshakeAlreadyStarted.java
→
of/
api/src/main/java/org/onlab/onos/of/controller/driver
/SwitchDriverSubHandshakeAlreadyStarted.java
View file @
6171f18
package
org
.
onlab
.
onos
.
of
.
controller
.
impl
.
internal
;
package
org
.
onlab
.
onos
.
of
.
controller
.
driver
;
/**
* Thrown when IOFSwitch.startDriverHandshake() is called more than once.
...
...
of/
ctl/src/main/java/org/onlab/onos/of/controller/impl/internal
/SwitchDriverSubHandshakeCompleted.java
→
of/
api/src/main/java/org/onlab/onos/of/controller/driver
/SwitchDriverSubHandshakeCompleted.java
View file @
6171f18
package
org
.
onlab
.
onos
.
of
.
controller
.
impl
.
internal
;
package
org
.
onlab
.
onos
.
of
.
controller
.
driver
;
import
org.projectfloodlight.openflow.protocol.OFMessage
;
...
...
of/
ctl/src/main/java/org/onlab/onos/of/controller/impl/internal
/SwitchDriverSubHandshakeException.java
→
of/
api/src/main/java/org/onlab/onos/of/controller/driver
/SwitchDriverSubHandshakeException.java
View file @
6171f18
package
org
.
onlab
.
onos
.
of
.
controller
.
impl
.
internal
;
package
org
.
onlab
.
onos
.
of
.
controller
.
driver
;
/**
* Base class for exception thrown by switch driver sub-handshake processing.
...
...
of/
ctl/src/main/java/org/onlab/onos/of/controller/impl/internal
/SwitchDriverSubHandshakeNotStarted.java
→
of/
api/src/main/java/org/onlab/onos/of/controller/driver
/SwitchDriverSubHandshakeNotStarted.java
View file @
6171f18
package
org
.
onlab
.
onos
.
of
.
controller
.
impl
.
internal
;
package
org
.
onlab
.
onos
.
of
.
controller
.
driver
;
/**
* Thrown when a switch driver's sub-handshake has not been started but an
...
...
of/
ctl/src/main/java/org/onlab/onos/of/controller/impl/internal
/SwitchDriverSubHandshakeStateException.java
→
of/
api/src/main/java/org/onlab/onos/of/controller/driver
/SwitchDriverSubHandshakeStateException.java
View file @
6171f18
package
org
.
onlab
.
onos
.
of
.
controller
.
impl
.
internal
;
package
org
.
onlab
.
onos
.
of
.
controller
.
driver
;
/**
* Thrown when a switch driver's sub-handshake state-machine receives an
...
...
of/
ctl/src/main/java/org/onlab/onos/of/controller/impl/internal
/SwitchStateException.java
→
of/
api/src/main/java/org/onlab/onos/of/controller/driver
/SwitchStateException.java
View file @
6171f18
...
...
@@ -15,7 +15,7 @@
* under the License.
**/
package
org
.
onlab
.
onos
.
of
.
controller
.
impl
.
internal
;
package
org
.
onlab
.
onos
.
of
.
controller
.
driver
;
/**
* This exception indicates an error or unexpected message during
...
...
of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/Controller.java
View file @
6171f18
...
...
@@ -30,9 +30,10 @@ import org.jboss.netty.channel.group.ChannelGroup;
import
org.jboss.netty.channel.group.DefaultChannelGroup
;
import
org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory
;
import
org.onlab.onos.of.controller.Dpid
;
import
org.onlab.onos.of.controller.driver.OpenFlowAgent
;
import
org.onlab.onos.of.controller.driver.OpenFlowSwitchDriver
;
import
org.onlab.onos.of.controller.impl.annotations.LogMessageDoc
;
import
org.onlab.onos.of.controller.impl.annotations.LogMessageDocs
;
import
org.onlab.onos.of.controller.impl.internal.OpenFlowControllerImpl.OpenFlowSwitchAgent
;
import
org.onlab.onos.of.drivers.DriverManager
;
import
org.projectfloodlight.openflow.protocol.OFDescStatsReply
;
import
org.projectfloodlight.openflow.protocol.OFFactories
;
...
...
@@ -74,7 +75,7 @@ public class Controller {
// Flag to always flush flow table on switch reconnect (HA or otherwise)
protected
boolean
alwaysClearFlowsOnSwAdd
=
false
;
private
OpenFlow
Switch
Agent
agent
;
private
OpenFlowAgent
agent
;
// Perf. related configuration
protected
static
final
int
SEND_BUFFER_SIZE
=
4
*
1024
*
1024
;
...
...
@@ -221,15 +222,16 @@ public class Controller {
* @param desc
* @return switch instance
*/
protected
AbstractOpenFlowSwitch
getOFSwitchInstance
(
long
dpid
,
protected
OpenFlowSwitchDriver
getOFSwitchInstance
(
long
dpid
,
OFDescStatsReply
desc
,
OFVersion
ofv
)
{
AbstractOpenFlowSwitch
sw
=
DriverManager
.
getOFSwitchImpl
(
new
Dpid
(
dpid
),
OpenFlowSwitchDriver
sw
=
DriverManager
.
getSwitch
(
new
Dpid
(
dpid
),
desc
,
ofv
);
sw
.
setAgent
(
agent
);
sw
.
setRoleHandler
(
new
RoleManager
(
sw
));
return
sw
;
}
public
void
start
(
OpenFlow
Switch
Agent
ag
)
{
public
void
start
(
OpenFlowAgent
ag
)
{
log
.
info
(
"Initialising OpenFlow Lib and IO"
);
this
.
agent
=
ag
;
this
.
init
(
new
HashMap
<
String
,
String
>());
...
...
of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/IOFSwitchManager.java
View file @
6171f18
package
org
.
onlab
.
onos
.
of
.
controller
.
impl
.
internal
;
import
org.onlab.onos.of.controller.driver.AbstractOpenFlowSwitch
;
import
org.projectfloodlight.openflow.protocol.OFVersion
;
...
...
of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/OFChannelHandler.java
View file @
6171f18
...
...
@@ -18,6 +18,8 @@ import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler;
import
org.jboss.netty.handler.timeout.IdleStateEvent
;
import
org.jboss.netty.handler.timeout.ReadTimeoutException
;
import
org.onlab.onos.of.controller.RoleState
;
import
org.onlab.onos.of.controller.driver.OpenFlowSwitchDriver
;
import
org.onlab.onos.of.controller.driver.SwitchStateException
;
import
org.onlab.onos.of.controller.impl.annotations.LogMessageDoc
;
import
org.onlab.onos.of.controller.impl.annotations.LogMessageDocs
;
import
org.projectfloodlight.openflow.exceptions.OFParseError
;
...
...
@@ -66,7 +68,7 @@ import org.slf4j.LoggerFactory;
class
OFChannelHandler
extends
IdleStateAwareChannelHandler
{
private
static
final
Logger
log
=
LoggerFactory
.
getLogger
(
OFChannelHandler
.
class
);
private
final
Controller
controller
;
private
AbstractOpenFlowSwitch
sw
;
private
OpenFlowSwitchDriver
sw
;
private
long
thisdpid
;
// channelHandler cached value of connected switch id
private
Channel
channel
;
// State needs to be volatile because the HandshakeTimeoutHandler
...
...
@@ -413,7 +415,7 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
OFDescStatsReply
drep
=
(
OFDescStatsReply
)
m
;
// Here is where we differentiate between different kinds of switches
h
.
sw
=
h
.
controller
.
getOFSwitchInstance
(
h
.
thisdpid
,
drep
,
h
.
ofVersion
);
boolean
success
=
h
.
sw
.
addConnected
Switch
();
boolean
success
=
h
.
sw
.
connect
Switch
();
if
(!
success
)
{
disconnectDuplicate
(
h
);
return
;
...
...
@@ -431,7 +433,7 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
//Put switch in EQUAL mode until we hear back from the global registry
log
.
debug
(
"Setting new switch {} to EQUAL and sending Role request"
,
h
.
sw
.
getStringId
());
h
.
sw
.
a
ddActivated
EqualSwitch
();
h
.
sw
.
a
ctivate
EqualSwitch
();
//h.setSwitchRole(RoleState.EQUAL);
h
.
setSwitchRole
(
RoleState
.
MASTER
);
h
.
sw
.
startDriverHandshake
();
...
...
of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/OpenFlowControllerImpl.java
View file @
6171f18
...
...
@@ -15,8 +15,9 @@ import org.onlab.onos.of.controller.OpenFlowSwitch;
import
org.onlab.onos.of.controller.OpenFlowSwitchListener
;
import
org.onlab.onos.of.controller.PacketListener
;
import
org.onlab.onos.of.controller.RoleState
;
import
org.onlab.onos.of.controller.driver.AbstractOpenFlowSwitch
;
import
org.onlab.onos.of.controller.driver.OpenFlowAgent
;
import
org.projectfloodlight.openflow.protocol.OFMessage
;
import
org.projectfloodlight.openflow.util.HexString
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
...
...
@@ -27,12 +28,12 @@ public class OpenFlowControllerImpl implements OpenFlowController {
private
static
final
Logger
log
=
LoggerFactory
.
getLogger
(
OpenFlowControllerImpl
.
class
);
protected
ConcurrentHashMap
<
Long
,
OpenFlowSwitch
>
connectedSwitches
=
new
ConcurrentHashMap
<
Long
,
OpenFlowSwitch
>();
protected
ConcurrentHashMap
<
Long
,
OpenFlowSwitch
>
activeMasterSwitches
=
new
ConcurrentHashMap
<
Long
,
OpenFlowSwitch
>();
protected
ConcurrentHashMap
<
Long
,
OpenFlowSwitch
>
activeEqualSwitches
=
new
ConcurrentHashMap
<
Long
,
OpenFlowSwitch
>();
protected
ConcurrentHashMap
<
Dpid
,
OpenFlowSwitch
>
connectedSwitches
=
new
ConcurrentHashMap
<
Dpid
,
OpenFlowSwitch
>();
protected
ConcurrentHashMap
<
Dpid
,
OpenFlowSwitch
>
activeMasterSwitches
=
new
ConcurrentHashMap
<
Dpid
,
OpenFlowSwitch
>();
protected
ConcurrentHashMap
<
Dpid
,
OpenFlowSwitch
>
activeEqualSwitches
=
new
ConcurrentHashMap
<
Dpid
,
OpenFlowSwitch
>();
protected
OpenFlowSwitchAgent
agent
=
new
OpenFlowSwitchAgent
();
protected
ArrayList
<
OpenFlowSwitchListener
>
ofEventListener
=
...
...
@@ -118,12 +119,13 @@ public class OpenFlowControllerImpl implements OpenFlowController {
((
AbstractOpenFlowSwitch
)
getSwitch
(
dpid
)).
setRole
(
role
);
}
public
class
OpenFlowSwitchAgent
{
public
class
OpenFlowSwitchAgent
implements
OpenFlowAgent
{
private
final
Logger
log
=
LoggerFactory
.
getLogger
(
OpenFlowSwitchAgent
.
class
);
private
Lock
switchLock
=
new
ReentrantLock
();
private
final
Lock
switchLock
=
new
ReentrantLock
();
public
boolean
addConnectedSwitch
(
long
dpid
,
AbstractOpenFlowSwitch
sw
)
{
@Override
public
boolean
addConnectedSwitch
(
Dpid
dpid
,
OpenFlowSwitch
sw
)
{
if
(
connectedSwitches
.
get
(
dpid
)
!=
null
)
{
log
.
error
(
"Trying to add connectedSwitch but found a previous "
+
"value for dpid: {}"
,
dpid
);
...
...
@@ -132,17 +134,18 @@ public class OpenFlowControllerImpl implements OpenFlowController {
log
.
error
(
"Added switch {}"
,
dpid
);
connectedSwitches
.
put
(
dpid
,
sw
);
for
(
OpenFlowSwitchListener
l
:
ofEventListener
)
{
l
.
switchAdded
(
new
Dpid
(
dpid
)
);
l
.
switchAdded
(
dpid
);
}
return
true
;
}
}
private
boolean
validActivation
(
long
dpid
)
{
@Override
public
boolean
validActivation
(
Dpid
dpid
)
{
if
(
connectedSwitches
.
get
(
dpid
)
==
null
)
{
log
.
error
(
"Trying to activate switch but is not in "
+
"connected switches: dpid {}. Aborting .."
,
HexString
.
toHexString
(
dpid
)
);
dpid
);
return
false
;
}
if
(
activeMasterSwitches
.
get
(
dpid
)
!=
null
||
...
...
@@ -150,7 +153,7 @@ public class OpenFlowControllerImpl implements OpenFlowController {
log
.
error
(
"Trying to activate switch but it is already "
+
"activated: dpid {}. Found in activeMaster: {} "
+
"Found in activeEqual: {}. Aborting .."
,
new
Object
[]
{
HexString
.
toHexString
(
dpid
)
,
dpid
,
(
activeMasterSwitches
.
get
(
dpid
)
==
null
)
?
'N'
:
'Y'
,
(
activeEqualSwitches
.
get
(
dpid
)
==
null
)
?
'N'
:
'Y'
});
return
false
;
...
...
@@ -158,10 +161,9 @@ public class OpenFlowControllerImpl implements OpenFlowController {
return
true
;
}
/**
* Called when a switch is activated, with this controller's role as MASTER.
*/
protected
boolean
addActivatedMasterSwitch
(
long
dpid
,
AbstractOpenFlowSwitch
sw
)
{
@Override
public
boolean
addActivatedMasterSwitch
(
Dpid
dpid
,
OpenFlowSwitch
sw
)
{
switchLock
.
lock
();
try
{
if
(!
validActivation
(
dpid
))
{
...
...
@@ -174,10 +176,8 @@ public class OpenFlowControllerImpl implements OpenFlowController {
}
}
/**
* Called when a switch is activated, with this controller's role as EQUAL.
*/
protected
boolean
addActivatedEqualSwitch
(
long
dpid
,
AbstractOpenFlowSwitch
sw
)
{
@Override
public
boolean
addActivatedEqualSwitch
(
Dpid
dpid
,
OpenFlowSwitch
sw
)
{
switchLock
.
lock
();
try
{
if
(!
validActivation
(
dpid
))
{
...
...
@@ -191,12 +191,8 @@ public class OpenFlowControllerImpl implements OpenFlowController {
}
}
/**
* Called when this controller's role for a switch transitions from equal
* to master. For 1.0 switches, we internally refer to the role 'slave' as
* 'equal' - so this transition is equivalent to 'addActivatedMasterSwitch'.
*/
protected
void
transitionToMasterSwitch
(
long
dpid
)
{
@Override
public
void
transitionToMasterSwitch
(
Dpid
dpid
)
{
switchLock
.
lock
();
try
{
if
(
activeMasterSwitches
.
containsKey
(
dpid
))
{
...
...
@@ -215,12 +211,8 @@ public class OpenFlowControllerImpl implements OpenFlowController {
}
/**
* Called when this controller's role for a switch transitions to equal.
* For 1.0 switches, we internally refer to the role 'slave' as
* 'equal'.
*/
protected
void
transitionToEqualSwitch
(
long
dpid
)
{
@Override
public
void
transitionToEqualSwitch
(
Dpid
dpid
)
{
switchLock
.
lock
();
try
{
if
(
activeEqualSwitches
.
containsKey
(
dpid
))
{
...
...
@@ -239,22 +231,19 @@ public class OpenFlowControllerImpl implements OpenFlowController {
}
/**
* Clear all state in controller switch maps for a switch that has
* disconnected from the local controller. Also release control for
* that switch from the global repository. Notify switch listeners.
*/
public
void
removeConnectedSwitch
(
long
dpid
)
{
@Override
public
void
removeConnectedSwitch
(
Dpid
dpid
)
{
connectedSwitches
.
remove
(
dpid
);
OpenFlowSwitch
sw
=
activeMasterSwitches
.
remove
(
dpid
);
if
(
sw
==
null
)
{
sw
=
activeEqualSwitches
.
remove
(
dpid
);
}
for
(
OpenFlowSwitchListener
l
:
ofEventListener
)
{
l
.
switchRemoved
(
new
Dpid
(
dpid
)
);
l
.
switchRemoved
(
dpid
);
}
}
@Override
public
void
processMessage
(
OFMessage
m
)
{
processPacket
(
m
);
}
...
...
of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/RoleManager.java
View file @
6171f18
...
...
@@ -4,6 +4,11 @@ import java.io.IOException;
import
java.util.Collections
;
import
org.onlab.onos.of.controller.RoleState
;
import
org.onlab.onos.of.controller.driver.OpenFlowSwitchDriver
;
import
org.onlab.onos.of.controller.driver.RoleHandler
;
import
org.onlab.onos.of.controller.driver.RoleRecvStatus
;
import
org.onlab.onos.of.controller.driver.RoleReplyInfo
;
import
org.onlab.onos.of.controller.driver.SwitchStateException
;
import
org.projectfloodlight.openflow.protocol.OFControllerRole
;
import
org.projectfloodlight.openflow.protocol.OFErrorMsg
;
import
org.projectfloodlight.openflow.protocol.OFErrorType
;
...
...
@@ -35,7 +40,7 @@ import org.slf4j.LoggerFactory;
* a new request is submitted before the timeout triggers. If necessary
* we could work around that though.
*/
class
RoleManager
{
class
RoleManager
implements
RoleHandler
{
protected
static
final
long
NICIRA_EXPERIMENTER
=
0x2320
;
private
static
Logger
log
=
LoggerFactory
.
getLogger
(
RoleManager
.
class
);
...
...
@@ -49,10 +54,10 @@ class RoleManager {
// the expectation set by the caller for the returned role
private
RoleRecvStatus
expectation
;
private
AbstractOpenFlowSwitch
sw
;
private
final
OpenFlowSwitchDriver
sw
;
public
RoleManager
(
AbstractOpenFlowSwitch
sw
)
{
public
RoleManager
(
OpenFlowSwitchDriver
sw
)
{
this
.
requestPending
=
false
;
this
.
pendingXid
=
-
1
;
this
.
pendingRole
=
null
;
...
...
@@ -122,33 +127,13 @@ class RoleManager {
return
xid
;
}
/**
* Send a role request with the given role to the switch and update
* the pending request and timestamp.
* Sends an OFPT_ROLE_REQUEST to an OF1.3 switch, OR
* Sends an NX_ROLE_REQUEST to an OF1.0 switch if configured to support it
* in the IOFSwitch driver. If not supported, this method sends nothing
* and returns 'false'. The caller should take appropriate action.
*
* One other optimization we do here is that for OF1.0 switches with
* Nicira role message support, we force the Role.EQUAL to become
* Role.SLAVE, as there is no defined behavior for the Nicira role OTHER.
* We cannot expect it to behave like SLAVE. We don't have this problem with
* OF1.3 switches, because Role.EQUAL is well defined and we can simulate
* SLAVE behavior by using ASYNC messages.
*
* @param role
* @throws IOException
* @returns false if and only if the switch does not support role-request
* messages, according to the switch driver; true otherwise.
*/
synchronized
boolean
sendRoleRequest
(
RoleState
role
,
RoleRecvStatus
exp
)
@Override
public
synchronized
boolean
sendRoleRequest
(
RoleState
role
,
RoleRecvStatus
exp
)
throws
IOException
{
this
.
expectation
=
exp
;
if
(
sw
.
factory
().
getVersion
()
==
OFVersion
.
OF_10
)
{
Boolean
supportsNxRole
=
(
Boolean
)
sw
.
supportNxRole
();
Boolean
supportsNxRole
=
sw
.
supportNxRole
();
if
(!
supportsNxRole
)
{
log
.
debug
(
"Switch driver indicates no support for Nicira "
+
"role request messages. Not sending ..."
);
...
...
@@ -189,23 +174,9 @@ class RoleManager {
}
/**
* Deliver a received role reply.
*
* Check if a request is pending and if the received reply matches the
* the expected pending reply (we check both role and xid) we set
* the role for the switch/channel.
*
* If a request is pending but doesn't match the reply we ignore it, and
* return
*
* If no request is pending we disconnect with a SwitchStateException
*
* @param RoleReplyInfo information about role-reply in format that
* controller can understand.
* @throws SwitchStateException if no request is pending
*/
synchronized
RoleRecvStatus
deliverRoleReply
(
RoleReplyInfo
rri
)
@Override
public
synchronized
RoleRecvStatus
deliverRoleReply
(
RoleReplyInfo
rri
)
throws
SwitchStateException
{
if
(!
requestPending
)
{
RoleState
currentRole
=
(
sw
!=
null
)
?
sw
.
getRole
()
:
null
;
...
...
@@ -280,7 +251,8 @@ class RoleManager {
* error messages for earlier role requests that we won't be able
* to handle
*/
synchronized
RoleRecvStatus
deliverError
(
OFErrorMsg
error
)
@Override
public
synchronized
RoleRecvStatus
deliverError
(
OFErrorMsg
error
)
throws
SwitchStateException
{
if
(!
requestPending
)
{
log
.
debug
(
"Received an error msg from sw {}, but no pending "
...
...
@@ -353,7 +325,8 @@ class RoleManager {
* @throws SwitchStateException If the message is a Nicira role reply
* but the numeric role value is unknown.
*/
protected
RoleState
extractNiciraRoleReply
(
OFExperimenter
experimenterMsg
)
@Override
public
RoleState
extractNiciraRoleReply
(
OFExperimenter
experimenterMsg
)
throws
SwitchStateException
{
int
vendor
=
(
int
)
experimenterMsg
.
getExperimenter
();
if
(
vendor
!=
0x2320
)
{
...
...
@@ -389,72 +362,14 @@ class RoleManager {
}
/**
* When we remove a pending role request we use this enum to indicate how we
* arrived at the decision. When we send a role request to the switch, we
* also use this enum to indicate what we expect back from the switch, so the
* role changer can match the reply to our expectation.
*/
public
enum
RoleRecvStatus
{
/** The switch returned an error indicating that roles are not.
* supported*/
UNSUPPORTED
,
/** The request timed out. */
NO_REPLY
,
/** The reply was old, there is a newer request pending. */
OLD_REPLY
,
/**
* The reply's role matched the role that this controller set in the
* request message - invoked either initially at startup or to reassert
* current role.
*/
MATCHED_CURRENT_ROLE
,
/**
* The reply's role matched the role that this controller set in the
* request message - this is the result of a callback from the
* global registry, followed by a role request sent to the switch.
*/
MATCHED_SET_ROLE
,
/**
* The reply's role was a response to the query made by this controller.
*/
REPLY_QUERY
,
/** We received a role reply message from the switch
* but the expectation was unclear, or there was no expectation.
*/
OTHER_EXPECTATION
,
}
/**
* Helper class returns role reply information in the format understood
* by the controller.
*/
protected
static
class
RoleReplyInfo
{
private
RoleState
role
;
private
U64
genId
;
private
long
xid
;
RoleReplyInfo
(
RoleState
role
,
U64
genId
,
long
xid
)
{
this
.
role
=
role
;
this
.
genId
=
genId
;
this
.
xid
=
xid
;
}
public
RoleState
getRole
()
{
return
role
;
}
public
U64
getGenId
()
{
return
genId
;
}
public
long
getXid
()
{
return
xid
;
}
@Override
public
String
toString
()
{
return
"[Role:"
+
role
+
" GenId:"
+
genId
+
" Xid:"
+
xid
+
"]"
;
}
}
/**
* Extract the role information from an OF1.3 Role Reply Message.
* @param h
* @param rrmsg
* @param rrmsg
the role message
* @return RoleReplyInfo object
* @throws SwitchStateException
* @throws SwitchStateException
if the role information could not be extracted.
*/
protected
RoleReplyInfo
extractOFRoleReply
(
OFRoleReply
rrmsg
)
@Override
public
RoleReplyInfo
extractOFRoleReply
(
OFRoleReply
rrmsg
)
throws
SwitchStateException
{
OFControllerRole
cr
=
rrmsg
.
getRole
();
RoleState
role
=
null
;
...
...
of/ctl/src/main/java/org/onlab/onos/of/drivers/DriverManager.java
View file @
6171f18
...
...
@@ -3,11 +3,9 @@ package org.onlab.onos.of.drivers;
import
org.onlab.onos.of.controller.Dpid
;
import
org.onlab.onos.of.controller.
RoleState
;
import
org.onlab.onos.of.controller.
impl.internal.AbstractOpenFlowSwitch
;
import
org.onlab.onos.of.controller.
driver.OpenFlowSwitchDriver
;
import
org.onlab.onos.of.controller.
driver.OpenFlowSwitchDriverFactory
;
import
org.projectfloodlight.openflow.protocol.OFDescStatsReply
;
import
org.projectfloodlight.openflow.protocol.OFFeaturesReply
;
import
org.projectfloodlight.openflow.protocol.OFMessage
;
import
org.projectfloodlight.openflow.protocol.OFVersion
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
...
...
@@ -16,7 +14,7 @@ import org.slf4j.LoggerFactory;
* A simple implementation of a driver manager that differentiates between
* connected switches using the OF Description Statistics Reply message.
*/
public
final
class
DriverManager
{
public
final
class
DriverManager
implements
OpenFlowSwitchDriverFactory
{
private
static
final
Logger
log
=
LoggerFactory
.
getLogger
(
DriverManager
.
class
);
...
...
@@ -32,7 +30,8 @@ public final class DriverManager {
* @return A IOFSwitch instance if the driver found an implementation for
* the given description. Otherwise it returns OFSwitchImplBase
*/
public
static
AbstractOpenFlowSwitch
getOFSwitchImpl
(
Dpid
dpid
,
@Override
public
OpenFlowSwitchDriver
getOFSwitchImpl
(
Dpid
dpid
,
OFDescStatsReply
desc
,
OFVersion
ofv
)
{
String
vendor
=
desc
.
getMfrDesc
();
String
hw
=
desc
.
getHwDesc
();
...
...
@@ -53,42 +52,7 @@ public final class DriverManager {
log
.
warn
(
"DriverManager could not identify switch desc: {}. "
+
"Assigning OFSwitchImplBase"
,
desc
);
AbstractOpenFlowSwitch
base
=
new
AbstractOpenFlowSwitch
(
dpid
)
{
@Override
public
void
sendMsg
(
OFMessage
m
)
{
channel
.
write
(
m
);
}
@Override
public
Boolean
supportNxRole
()
{
return
false
;
}
@Override
public
void
startDriverHandshake
()
{}
@Override
public
void
setFeaturesReply
(
OFFeaturesReply
featuresReply
)
{
this
.
features
=
featuresReply
;
}
@Override
public
void
processDriverHandshakeMessage
(
OFMessage
m
)
{}
@Override
public
boolean
isDriverHandshakeComplete
()
{
return
true
;
}
@Override
public
RoleState
getRole
()
{
return
role
;
}
};
base
.
setSwitchDescription
(
desc
);
return
base
;
return
null
;
}
/**
...
...
@@ -108,4 +72,10 @@ public final class DriverManager {
public
static
void
setConfigForCpqd
(
boolean
usePipeline13
)
{
cpqdUsePipeline13
=
usePipeline13
;
}
public
static
OpenFlowSwitchDriver
getSwitch
(
Dpid
dpid
,
OFDescStatsReply
desc
,
OFVersion
ofv
)
{
return
new
DriverManager
().
getOFSwitchImpl
(
dpid
,
desc
,
ofv
);
}
}
...
...
of/ctl/src/main/java/org/onlab/onos/of/drivers/OFSwitchImplCPqD13.java
View file @
6171f18
...
...
@@ -10,15 +10,14 @@ import java.util.concurrent.atomic.AtomicBoolean;
import
org.onlab.onos.of.controller.Dpid
;
import
org.onlab.onos.of.controller.RoleState
;
import
org.onlab.onos.of.controller.
impl.internal
.AbstractOpenFlowSwitch
;
import
org.onlab.onos.of.controller.
impl.internal
.SwitchDriverSubHandshakeAlreadyStarted
;
import
org.onlab.onos.of.controller.
impl.internal
.SwitchDriverSubHandshakeCompleted
;
import
org.onlab.onos.of.controller.
impl.internal
.SwitchDriverSubHandshakeNotStarted
;
import
org.onlab.onos.of.controller.
driver
.AbstractOpenFlowSwitch
;
import
org.onlab.onos.of.controller.
driver
.SwitchDriverSubHandshakeAlreadyStarted
;
import
org.onlab.onos.of.controller.
driver
.SwitchDriverSubHandshakeCompleted
;
import
org.onlab.onos.of.controller.
driver
.SwitchDriverSubHandshakeNotStarted
;
import
org.projectfloodlight.openflow.protocol.OFAsyncGetReply
;
import
org.projectfloodlight.openflow.protocol.OFBarrierRequest
;
import
org.projectfloodlight.openflow.protocol.OFBucket
;
import
org.projectfloodlight.openflow.protocol.OFDescStatsReply
;
import
org.projectfloodlight.openflow.protocol.OFErrorMsg
;
import
org.projectfloodlight.openflow.protocol.OFFactory
;
import
org.projectfloodlight.openflow.protocol.OFGroupDescStatsReply
;
import
org.projectfloodlight.openflow.protocol.OFGroupFeaturesStatsReply
;
...
...
@@ -61,11 +60,11 @@ import org.slf4j.LoggerFactory;
*/
public
class
OFSwitchImplCPqD13
extends
AbstractOpenFlowSwitch
{
private
Logger
log
=
private
final
Logger
log
=
LoggerFactory
.
getLogger
(
OFSwitchImplCPqD13
.
class
);
private
static
final
int
VLAN_ID_OFFSET
=
16
;
private
AtomicBoolean
driverHandshakeComplete
;
private
final
AtomicBoolean
driverHandshakeComplete
;
private
OFFactory
factory
;
private
static
final
int
OFPCML_NO_BUFFER
=
0xffff
;
// Configuration of asynch messages to controller. We need different
...
...
@@ -96,7 +95,7 @@ public class OFSwitchImplCPqD13 extends AbstractOpenFlowSwitch {
private
static
final
short
MIN_PRIORITY
=
0x0
;
private
static
final
U64
METADATA_MASK
=
U64
.
of
(
Long
.
MAX_VALUE
<<
1
|
0x1
);
private
Map
<
Integer
,
OFGroup
>
l2groups
;
private
final
Map
<
Integer
,
OFGroup
>
l2groups
;
private
final
boolean
usePipeline13
;
...
...
@@ -146,14 +145,7 @@ public class OFSwitchImplCPqD13 extends AbstractOpenFlowSwitch {
@Override
public
void
processDriverHandshakeMessage
(
OFMessage
m
)
{
if
(!
startDriverHandshakeCalled
)
{
throw
new
SwitchDriverSubHandshakeNotStarted
();
}
if
(
driverHandshakeComplete
.
get
())
{
throw
new
SwitchDriverSubHandshakeCompleted
(
m
);
}
if
(!
startDriverHandshakeCalled
)
{
if
(!
startDriverHandshakeCalled
||
!
startDriverHandshakeCalled
)
{
throw
new
SwitchDriverSubHandshakeNotStarted
();
}
if
(
driverHandshakeComplete
.
get
())
{
...
...
@@ -168,29 +160,22 @@ public class OFSwitchImplCPqD13 extends AbstractOpenFlowSwitch {
break
;
case
ERROR:
log
.
error
(
"Switch {} Error {}"
,
getStringId
(),
(
OFErrorMsg
)
m
);
log
.
error
(
"Switch {} Error {}"
,
getStringId
(),
m
);
break
;
case
FEATURES_REPLY:
break
;
case
FLOW_REMOVED:
break
;
case
GET_ASYNC_REPLY:
OFAsyncGetReply
asrep
=
(
OFAsyncGetReply
)
m
;
decodeAsyncGetReply
(
asrep
);
break
;
case
PACKET_IN:
case
STATS_REPLY:
processStatsReply
((
OFStatsReply
)
m
);
break
;
case
PACKET_IN:
case
PORT_STATUS:
break
;
case
QUEUE_GET_CONFIG_REPLY:
break
;
case
ROLE_REPLY:
break
;
case
STATS_REPLY:
processStatsReply
((
OFStatsReply
)
m
);
case
FEATURES_REPLY:
case
FLOW_REMOVED:
break
;
default
:
...
...
@@ -254,7 +239,7 @@ public class OFSwitchImplCPqD13 extends AbstractOpenFlowSwitch {
.
build
();
msglist
.
add
(
getAC
);
write
(
msglist
);
sendMsg
(
msglist
);
}
private
void
decodeAsyncGetReply
(
OFAsyncGetReply
rep
)
{
...
...
@@ -327,7 +312,7 @@ public class OFSwitchImplCPqD13 extends AbstractOpenFlowSwitch {
}
}
log
.
debug
(
"Creating {} L2 groups in sw {}"
,
msglist
.
size
(),
getStringId
());
write
(
msglist
);
sendMsg
(
msglist
);
}
private
int
getVlanConfig
(
int
portnum
)
{
...
...
@@ -428,7 +413,7 @@ public class OFSwitchImplCPqD13 extends AbstractOpenFlowSwitch {
.
build
();
msglist
.
add
(
gmAdd
);
}
write
(
msglist
);
sendMsg
(
msglist
);
log
.
debug
(
"Creating {} L3 groups in sw {}"
,
msglist
.
size
(),
getStringId
());
}
...
...
@@ -480,7 +465,7 @@ public class OFSwitchImplCPqD13 extends AbstractOpenFlowSwitch {
msglist
.
add
(
gmAdd
);
}
}
write
(
msglist
);
sendMsg
(
msglist
);
log
.
debug
(
"Creating {} MPLS groups in sw {}"
,
msglist
.
size
(),
getStringId
());
}
...
...
@@ -597,7 +582,7 @@ public class OFSwitchImplCPqD13 extends AbstractOpenFlowSwitch {
}
// table-vlan has no table-miss entry, and so packets that miss are
// essentially dropped
write
(
msglist
);
sendMsg
(
msglist
);
log
.
debug
(
"Adding {} vlan-rules in sw {}"
,
msglist
.
size
(),
getStringId
());
}
...
...
@@ -649,7 +634,7 @@ public class OFSwitchImplCPqD13 extends AbstractOpenFlowSwitch {
List
<
OFMessage
>
msglist
=
new
ArrayList
<
OFMessage
>(
2
);
msglist
.
add
(
ipEntry
);
msglist
.
add
(
mplsEntry
);
write
(
msglist
);
sendMsg
(
msglist
);
}
private
List
<
String
>
getMyIps
()
{
// send to controller
...
...
@@ -802,7 +787,7 @@ public class OFSwitchImplCPqD13 extends AbstractOpenFlowSwitch {
.
build
();
msglist
.
add
(
myIpEntry
);
}
write
(
msglist
);
sendMsg
(
msglist
);
log
.
debug
(
"Adding {} my-ip-rules in sw {}"
,
msglist
.
size
(),
getStringId
());
}
...
...
@@ -844,7 +829,7 @@ public class OFSwitchImplCPqD13 extends AbstractOpenFlowSwitch {
.
build
();
msglist
.
add
(
myIpEntry
);
}
write
(
msglist
);
sendMsg
(
msglist
);
log
.
debug
(
"Adding {} subnet-ip-rules in sw {}"
,
msglist
.
size
(),
getStringId
());
msglist
.
clear
();
}
...
...
@@ -989,7 +974,7 @@ public class OFSwitchImplCPqD13 extends AbstractOpenFlowSwitch {
msglist
.
add
(
myMetaEntry
);
}
write
(
msglist
);
sendMsg
(
msglist
);
log
.
debug
(
"Adding {} next-hop-router-rules in sw {}"
,
msglist
.
size
(),
getStringId
());
...
...
@@ -1047,7 +1032,7 @@ public class OFSwitchImplCPqD13 extends AbstractOpenFlowSwitch {
.
build
();
msglist
.
add
(
myIpEntry
);
}
write
(
msglist
);
sendMsg
(
msglist
);
log
.
debug
(
"Adding {} next-hop-host-rules in sw {}"
,
msglist
.
size
(),
getStringId
());
}
...
...
@@ -1121,7 +1106,7 @@ public class OFSwitchImplCPqD13 extends AbstractOpenFlowSwitch {
.
build
();
msglist
.
add
(
myMplsEntry
);
}
write
(
msglist
);
sendMsg
(
msglist
);
log
.
debug
(
"Adding {} mpls-forwarding-rules in sw {}"
,
msglist
.
size
(),
getStringId
());
...
...
@@ -1190,7 +1175,7 @@ public class OFSwitchImplCPqD13 extends AbstractOpenFlowSwitch {
// executed - if there is an action to output/group in the action
// set
// the packet will be sent there, otherwise it will be dropped.
instructions
=
(
List
<
OFInstruction
>)
Collections
.
EMPTY_LIST
;
instructions
=
Collections
.
EMPTY_LIST
;
}
OFMessage
tableMissEntry
=
factory
.
buildFlowAdd
()
...
...
@@ -1219,20 +1204,19 @@ public class OFSwitchImplCPqD13 extends AbstractOpenFlowSwitch {
}
@Override
public
void
sendMsg
(
OFMessage
m
)
{
channel
.
write
(
m
)
;
public
Boolean
supportNxRole
(
)
{
return
false
;
}
@Override
public
void
write
(
List
<
OFMessage
>
msgs
)
{
for
(
OFMessage
m
:
msgs
)
{
channel
.
write
(
m
);
}
public
void
write
(
OFMessage
msg
)
{
this
.
channel
.
write
(
msg
);
}
@Override
public
Boolean
supportNxRole
(
)
{
return
false
;
public
void
write
(
List
<
OFMessage
>
msgs
)
{
this
.
channel
.
write
(
msgs
)
;
}
}
...
...
of/ctl/src/main/java/org/onlab/onos/of/drivers/OFSwitchImplOVS10.java
View file @
6171f18
package
org
.
onlab
.
onos
.
of
.
drivers
;
import
java.util.List
;
import
org.onlab.onos.of.controller.Dpid
;
import
org.onlab.onos.of.controller.
impl.internal
.AbstractOpenFlowSwitch
;
import
org.onlab.onos.of.controller.
driver
.AbstractOpenFlowSwitch
;
import
org.projectfloodlight.openflow.protocol.OFDescStatsReply
;
import
org.projectfloodlight.openflow.protocol.OFMessage
;
...
...
@@ -29,11 +31,6 @@ public class OFSwitchImplOVS10 extends AbstractOpenFlowSwitch {
}
@Override
public
void
sendMsg
(
OFMessage
m
)
{
channel
.
write
(
m
);
}
@Override
public
Boolean
supportNxRole
()
{
return
true
;
}
...
...
@@ -48,4 +45,15 @@ public class OFSwitchImplOVS10 extends AbstractOpenFlowSwitch {
@Override
public
void
processDriverHandshakeMessage
(
OFMessage
m
)
{}
@Override
public
void
write
(
OFMessage
msg
)
{
channel
.
write
(
msg
);
}
@Override
public
void
write
(
List
<
OFMessage
>
msgs
)
{
channel
.
write
(
msgs
);
}
}
...
...
of/ctl/src/main/java/org/onlab/onos/of/drivers/OFSwitchImplOVS13.java
View file @
6171f18
package
org
.
onlab
.
onos
.
of
.
drivers
;
import
java.util.List
;
import
java.util.concurrent.atomic.AtomicBoolean
;
import
org.onlab.onos.of.controller.Dpid
;
import
org.onlab.onos.of.controller.
impl.internal
.AbstractOpenFlowSwitch
;
import
org.onlab.onos.of.controller.
impl.internal
.SwitchDriverSubHandshakeAlreadyStarted
;
import
org.onlab.onos.of.controller.
impl.internal
.SwitchDriverSubHandshakeCompleted
;
import
org.onlab.onos.of.controller.
impl.internal
.SwitchDriverSubHandshakeNotStarted
;
import
org.onlab.onos.of.controller.
driver
.AbstractOpenFlowSwitch
;
import
org.onlab.onos.of.controller.
driver
.SwitchDriverSubHandshakeAlreadyStarted
;
import
org.onlab.onos.of.controller.
driver
.SwitchDriverSubHandshakeCompleted
;
import
org.onlab.onos.of.controller.
driver
.SwitchDriverSubHandshakeNotStarted
;
import
org.projectfloodlight.openflow.protocol.OFBarrierRequest
;
import
org.projectfloodlight.openflow.protocol.OFDescStatsReply
;
import
org.projectfloodlight.openflow.protocol.OFErrorMsg
;
import
org.projectfloodlight.openflow.protocol.OFFactory
;
import
org.projectfloodlight.openflow.protocol.OFMessage
;
import
org.slf4j.Logger
;
...
...
@@ -25,7 +25,7 @@ public class OFSwitchImplOVS13 extends AbstractOpenFlowSwitch {
private
static
Logger
log
=
LoggerFactory
.
getLogger
(
OFSwitchImplOVS13
.
class
);
private
AtomicBoolean
driverHandshakeComplete
;
private
final
AtomicBoolean
driverHandshakeComplete
;
private
OFFactory
factory
;
private
long
barrierXidToWaitFor
=
-
1
;
...
...
@@ -78,7 +78,7 @@ public class OFSwitchImplOVS13 extends AbstractOpenFlowSwitch {
break
;
case
ERROR:
log
.
error
(
"Switch {} Error {}"
,
getStringId
(),
(
OFErrorMsg
)
m
);
log
.
error
(
"Switch {} Error {}"
,
getStringId
(),
m
);
break
;
case
FEATURES_REPLY:
...
...
@@ -129,12 +129,18 @@ public class OFSwitchImplOVS13 extends AbstractOpenFlowSwitch {
}
@Override
public
void
sendMsg
(
OFMessage
m
)
{
channel
.
write
(
m
)
;
public
Boolean
supportNxRole
(
)
{
return
false
;
}
@Override
public
Boolean
supportNxRole
()
{
return
false
;
public
void
write
(
OFMessage
msg
)
{
channel
.
write
(
msg
);
}
@Override
public
void
write
(
List
<
OFMessage
>
msgs
)
{
channel
.
write
(
msgs
);
}
}
...
...
Please
register
or
login
to post a comment