Fix checkstyle whitespace issues - WHITESPACE ONLY
Change-Id: Ic205c1afd639c6008d61d9de95cb764eeb6238ca
diff --git a/src/main/java/net/floodlightcontroller/core/internal/CmdLineSettings.java b/src/main/java/net/floodlightcontroller/core/internal/CmdLineSettings.java
index 7641a7c..d2d74c4 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/CmdLineSettings.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/CmdLineSettings.java
@@ -8,10 +8,10 @@
public class CmdLineSettings {
public static final String DEFAULT_CONFIG_FILE = "config/floodlight.properties";
- @Option(name="-cf", aliases="--configFile", metaVar="FILE", usage="Floodlight configuration file")
+ @Option(name = "-cf", aliases = "--configFile", metaVar = "FILE", usage = "Floodlight configuration file")
private String configFile = DEFAULT_CONFIG_FILE;
-
+
public String getModuleFile() {
- return configFile;
+ return configFile;
}
}
diff --git a/src/main/java/net/floodlightcontroller/core/internal/Controller.java b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
index d475fa6..74f0802 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/Controller.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
@@ -1,19 +1,19 @@
/**
-* 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.
-**/
+ * 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.internal;
@@ -124,26 +124,26 @@
/**
* The main controller class. Handles all setup and network listeners
- *
+ * <p/>
* Extensions made by ONOS are:
- * - Detailed Port event: PORTCHANGED -> {PORTCHANGED, PORTADDED, PORTREMOVED}
- * Available as net.onrc.onos.core.main.IOFSwitchPortListener
+ * - Detailed Port event: PORTCHANGED -> {PORTCHANGED, PORTADDED, PORTREMOVED}
+ * Available as net.onrc.onos.core.main.IOFSwitchPortListener
* - Distributed ownership control of switch through RegistryService(IControllerRegistryService)
* - Register ONOS services. (IControllerRegistryService)
* - Additional DEBUG logs
* - Try using hostname as controller ID, when ID was not explicitly given.
*/
public class Controller implements IFloodlightProviderService {
-
+
protected final static Logger log = LoggerFactory.getLogger(Controller.class);
- private static final String ERROR_DATABASE =
+ private static final String ERROR_DATABASE =
"The controller could not communicate with the system database.";
-
+
protected BasicFactory factory;
protected ConcurrentMap<OFType,
- ListenerDispatcher<OFType,IOFMessageListener>>
- messageListeners;
+ ListenerDispatcher<OFType, IOFMessageListener>>
+ messageListeners;
// The activeSwitches map contains only those switches that are actively
// being controlled by us -- it doesn't contain switches that are
// in the slave role
@@ -154,45 +154,45 @@
// We add a switch to this set after it successfully completes the
// handshake. Access to this Set needs to be synchronized with roleChanger
protected HashSet<OFSwitchImpl> connectedSwitches;
-
+
// The controllerNodeIPsCache maps Controller IDs to their IP address.
// It's only used by handleControllerNodeIPsChanged
protected HashMap<String, String> controllerNodeIPsCache;
-
+
protected Set<IOFSwitchListener> switchListeners;
protected BlockingQueue<IUpdate> updates;
-
+
// Module dependencies
protected IRestApiService restApi;
protected IThreadPoolService threadPool;
protected IControllerRegistryService registryService;
-
+
protected ILinkDiscoveryService linkDiscovery;
-
+
// Configuration options
protected int openFlowPort = 6633;
protected int workerThreads = 0;
// The id for this controller node. Should be unique for each controller
// node in a controller cluster.
protected String controllerId = "localhost";
-
+
// The current role of the controller.
// If the controller isn't configured to support roles, then this is null.
protected Role role;
// A helper that handles sending and timeout handling for role requests
protected RoleChanger roleChanger;
-
+
// Start time of the controller
protected long systemStartTime;
-
+
// Flag to always flush flow table on switch reconnect (HA or otherwise)
protected boolean alwaysClearFlowsOnSwAdd = false;
-
+
// Perf. related configuration
protected static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024;
protected static final int BATCH_MAX_SIZE = 100;
- protected static final boolean ALWAYS_DECODE_ETH = true;
-
+ protected static final boolean ALWAYS_DECODE_ETH = true;
+
public enum SwitchUpdateType {
ADDED,
REMOVED,
@@ -200,24 +200,27 @@
PORTADDED,
PORTREMOVED
}
-
+
/**
- * Update message indicating a switch was added or removed
+ * Update message indicating a switch was added or removed
* ONOS: This message extended to indicate Port add or removed event.
*/
protected class SwitchUpdate implements IUpdate {
public IOFSwitch sw;
public OFPhysicalPort port; // Added by ONOS
public SwitchUpdateType switchUpdateType;
+
public SwitchUpdate(IOFSwitch sw, SwitchUpdateType switchUpdateType) {
this.sw = sw;
this.switchUpdateType = switchUpdateType;
}
+
public SwitchUpdate(IOFSwitch sw, OFPhysicalPort port, SwitchUpdateType switchUpdateType) {
this.sw = sw;
this.port = port;
this.switchUpdateType = switchUpdateType;
}
+
public void dispatch() {
if (log.isTraceEnabled()) {
log.trace("Dispatching switch update {} {}",
@@ -225,7 +228,7 @@
}
if (switchListeners != null) {
for (IOFSwitchListener listener : switchListeners) {
- switch(switchUpdateType) {
+ switch (switchUpdateType) {
case ADDED:
listener.addedSwitch(sw);
break;
@@ -236,138 +239,139 @@
listener.switchPortChanged(sw.getId());
break;
case PORTADDED:
- if (listener instanceof IOFSwitchPortListener) {
- ((IOFSwitchPortListener) listener).switchPortAdded(sw.getId(), port);
- }
- break;
+ if (listener instanceof IOFSwitchPortListener) {
+ ((IOFSwitchPortListener) listener).switchPortAdded(sw.getId(), port);
+ }
+ break;
case PORTREMOVED:
- if (listener instanceof IOFSwitchPortListener) {
- ((IOFSwitchPortListener) listener).switchPortRemoved(sw.getId(), port);
- }
- break;
+ if (listener instanceof IOFSwitchPortListener) {
+ ((IOFSwitchPortListener) listener).switchPortRemoved(sw.getId(), port);
+ }
+ break;
default:
- break;
+ break;
}
}
}
}
}
-
+
// ***************
// Getters/Setters
// ***************
-
+
public void setRestApiService(IRestApiService restApi) {
this.restApi = restApi;
}
-
+
public void setThreadPoolService(IThreadPoolService tp) {
this.threadPool = tp;
}
- public void setMastershipService(IControllerRegistryService serviceImpl) {
- this.registryService = serviceImpl;
- }
-
- public void setLinkDiscoveryService(ILinkDiscoveryService linkDiscovery) {
- this.linkDiscovery = linkDiscovery;
- }
-
- public void publishUpdate(IUpdate update) {
- try {
- this.updates.put(update);
- } catch (InterruptedException e) {
- log.error("Failure adding update to queue", e);
- }
+ public void setMastershipService(IControllerRegistryService serviceImpl) {
+ this.registryService = serviceImpl;
}
-
+
+ public void setLinkDiscoveryService(ILinkDiscoveryService linkDiscovery) {
+ this.linkDiscovery = linkDiscovery;
+ }
+
+ public void publishUpdate(IUpdate update) {
+ try {
+ this.updates.put(update);
+ } catch (InterruptedException e) {
+ log.error("Failure adding update to queue", e);
+ }
+ }
+
// **********************
// ChannelUpstreamHandler
// **********************
-
+
/**
* Return a new channel handler for processing a switch connections
+ *
* @param state The channel state object for the connection
* @return the new channel handler
*/
protected ChannelUpstreamHandler getChannelHandler(OFChannelState state) {
return new OFChannelHandler(state);
}
-
+
protected class RoleChangeCallback implements ControlChangeCallback {
- @Override
- public void controlChanged(long dpid, boolean hasControl) {
- log.info("Role change callback for switch {}, hasControl {}",
- HexString.toHexString(dpid), hasControl);
-
- synchronized(roleChanger){
- OFSwitchImpl sw = null;
- for (OFSwitchImpl connectedSw : connectedSwitches){
- if (connectedSw.getId() == dpid){
- sw = connectedSw;
- break;
- }
- }
- if (sw == null){
- log.warn("Switch {} not found in connected switches",
- HexString.toHexString(dpid));
- return;
- }
-
- Role role = null;
-
- /*
- * issue #229
- * Cannot rely on sw.getRole() as it can be behind due to pending
- * role changes in the queue. Just submit it and late the RoleChanger
- * handle duplicates.
- */
+ @Override
+ public void controlChanged(long dpid, boolean hasControl) {
+ log.info("Role change callback for switch {}, hasControl {}",
+ HexString.toHexString(dpid), hasControl);
- if (hasControl){
- role = Role.MASTER;
- }
- else {
- role = Role.SLAVE;
- }
+ synchronized (roleChanger) {
+ OFSwitchImpl sw = null;
+ for (OFSwitchImpl connectedSw : connectedSwitches) {
+ if (connectedSw.getId() == dpid) {
+ sw = connectedSw;
+ break;
+ }
+ }
+ if (sw == null) {
+ log.warn("Switch {} not found in connected switches",
+ HexString.toHexString(dpid));
+ return;
+ }
- log.debug("Sending role request {} msg to {}", role, sw);
- Collection<OFSwitchImpl> swList = new ArrayList<OFSwitchImpl>(1);
- swList.add(sw);
- roleChanger.submitRequest(swList, role);
+ Role role = null;
+
+ /*
+ * issue #229
+ * Cannot rely on sw.getRole() as it can be behind due to pending
+ * role changes in the queue. Just submit it and late the RoleChanger
+ * handle duplicates.
+ */
- }
-
- }
+ if (hasControl) {
+ role = Role.MASTER;
+ } else {
+ role = Role.SLAVE;
+ }
+
+ log.debug("Sending role request {} msg to {}", role, sw);
+ Collection<OFSwitchImpl> swList = new ArrayList<OFSwitchImpl>(1);
+ swList.add(sw);
+ roleChanger.submitRequest(swList, role);
+
+ }
+
+ }
}
-
+
/**
* Channel handler deals with the switch connection and dispatches
* switch messages to the appropriate locations.
+ *
* @author readams
*/
- protected class OFChannelHandler
- extends IdleStateAwareChannelUpstreamHandler {
+ protected class OFChannelHandler
+ extends IdleStateAwareChannelUpstreamHandler {
protected OFSwitchImpl sw;
protected OFChannelState state;
-
+
public OFChannelHandler(OFChannelState state) {
this.state = state;
}
@Override
- @LogMessageDoc(message="New switch connection from {ip address}",
- explanation="A new switch has connected from the " +
- "specified IP address")
+ @LogMessageDoc(message = "New switch connection from {ip address}",
+ explanation = "A new switch has connected from the " +
+ "specified IP address")
public void channelConnected(ChannelHandlerContext ctx,
ChannelStateEvent e) throws Exception {
log.info("New switch connection from {}",
- e.getChannel().getRemoteAddress());
-
+ e.getChannel().getRemoteAddress());
+
sw = new OFSwitchImpl();
sw.setChannel(e.getChannel());
sw.setFloodlightProvider(Controller.this);
sw.setThreadPoolService(threadPool);
-
+
List<OFMessage> msglist = new ArrayList<OFMessage>(1);
msglist.add(factory.getMessage(OFType.HELLO));
e.getChannel().write(msglist);
@@ -375,8 +379,8 @@
}
@Override
- @LogMessageDoc(message="Disconnected switch {switch information}",
- explanation="The specified switch has disconnected.")
+ @LogMessageDoc(message = "Disconnected switch {switch information}",
+ explanation = "The specified switch has disconnected.")
public void channelDisconnected(ChannelHandlerContext ctx,
ChannelStateEvent e) throws Exception {
if (sw != null && state.hsState == HandshakeState.READY) {
@@ -386,10 +390,10 @@
// same DPID
removeSwitch(sw);
}
- synchronized(roleChanger) {
- if (controlRequested) {
- registryService.releaseControl(sw.getId());
- }
+ synchronized (roleChanger) {
+ if (controlRequested) {
+ registryService.releaseControl(sw.getId());
+ }
connectedSwitches.remove(sw);
}
sw.setConnected(false);
@@ -399,41 +403,41 @@
@Override
@LogMessageDocs({
- @LogMessageDoc(level="ERROR",
- message="Disconnecting switch {switch} due to read timeout",
- explanation="The connected switch has failed to send any " +
+ @LogMessageDoc(level = "ERROR",
+ message = "Disconnecting switch {switch} due to read timeout",
+ explanation = "The connected switch has failed to send any " +
"messages or respond to echo requests",
- recommendation=LogMessageDoc.CHECK_SWITCH),
- @LogMessageDoc(level="ERROR",
- message="Disconnecting switch {switch}: failed to " +
- "complete handshake",
- explanation="The switch did not respond correctly " +
+ recommendation = LogMessageDoc.CHECK_SWITCH),
+ @LogMessageDoc(level = "ERROR",
+ message = "Disconnecting switch {switch}: failed to " +
+ "complete handshake",
+ explanation = "The switch did not respond correctly " +
"to handshake messages",
- recommendation=LogMessageDoc.CHECK_SWITCH),
- @LogMessageDoc(level="ERROR",
- message="Disconnecting switch {switch} due to IO Error: {}",
- explanation="There was an error communicating with the switch",
- recommendation=LogMessageDoc.CHECK_SWITCH),
- @LogMessageDoc(level="ERROR",
- message="Disconnecting switch {switch} due to switch " +
- "state error: {error}",
- explanation="The switch sent an unexpected message",
- recommendation=LogMessageDoc.CHECK_SWITCH),
- @LogMessageDoc(level="ERROR",
- message="Disconnecting switch {switch} due to " +
- "message parse failure",
- explanation="Could not parse a message from the switch",
- recommendation=LogMessageDoc.CHECK_SWITCH),
- @LogMessageDoc(level="ERROR",
- message="Could not process message: queue full",
- explanation="OpenFlow messages are arriving faster than " +
+ recommendation = LogMessageDoc.CHECK_SWITCH),
+ @LogMessageDoc(level = "ERROR",
+ message = "Disconnecting switch {switch} due to IO Error: {}",
+ explanation = "There was an error communicating with the switch",
+ recommendation = LogMessageDoc.CHECK_SWITCH),
+ @LogMessageDoc(level = "ERROR",
+ message = "Disconnecting switch {switch} due to switch " +
+ "state error: {error}",
+ explanation = "The switch sent an unexpected message",
+ recommendation = LogMessageDoc.CHECK_SWITCH),
+ @LogMessageDoc(level = "ERROR",
+ message = "Disconnecting switch {switch} due to " +
+ "message parse failure",
+ explanation = "Could not parse a message from the switch",
+ recommendation = LogMessageDoc.CHECK_SWITCH),
+ @LogMessageDoc(level = "ERROR",
+ message = "Could not process message: queue full",
+ explanation = "OpenFlow messages are arriving faster than " +
" the controller can process them.",
- recommendation=LogMessageDoc.CHECK_CONTROLLER),
- @LogMessageDoc(level="ERROR",
- message="Error while processing message " +
- "from switch {switch} {cause}",
- explanation="An error occurred processing the switch message",
- recommendation=LogMessageDoc.GENERIC_ACTION)
+ recommendation = LogMessageDoc.CHECK_CONTROLLER),
+ @LogMessageDoc(level = "ERROR",
+ message = "Error while processing message " +
+ "from switch {switch} {cause}",
+ explanation = "An error occurred processing the switch message",
+ recommendation = LogMessageDoc.GENERIC_ACTION)
})
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
throws Exception {
@@ -442,29 +446,29 @@
log.error("Disconnecting switch {} due to read timeout", sw);
ctx.getChannel().close();
} else if (e.getCause() instanceof HandshakeTimeoutException) {
- log.error("Disconnecting switch {}: failed to complete handshake",
- sw);
+ log.error("Disconnecting switch {}: failed to complete handshake",
+ sw);
ctx.getChannel().close();
} else if (e.getCause() instanceof ClosedChannelException) {
//log.warn("Channel for sw {} already closed", sw);
} else if (e.getCause() instanceof IOException) {
log.error("Disconnecting switch {} due to IO Error: {}",
- sw, e.getCause().getMessage());
+ sw, e.getCause().getMessage());
ctx.getChannel().close();
} else if (e.getCause() instanceof SwitchStateException) {
- log.error("Disconnecting switch {} due to switch state error: {}",
- sw, e.getCause().getMessage());
+ log.error("Disconnecting switch {} due to switch state error: {}",
+ sw, e.getCause().getMessage());
ctx.getChannel().close();
} else if (e.getCause() instanceof MessageParseException) {
log.error("Disconnecting switch " + sw +
- " due to message parse failure",
- e.getCause());
+ " due to message parse failure",
+ e.getCause());
ctx.getChannel().close();
} else if (e.getCause() instanceof RejectedExecutionException) {
log.warn("Could not process message: queue full");
} else {
log.error("Error while processing message from switch " + sw,
- e.getCause());
+ e.getCause());
ctx.getChannel().close();
}
}
@@ -482,13 +486,12 @@
throws Exception {
if (e.getMessage() instanceof List) {
@SuppressWarnings("unchecked")
- List<OFMessage> msglist = (List<OFMessage>)e.getMessage();
+ List<OFMessage> msglist = (List<OFMessage>) e.getMessage();
for (OFMessage ofm : msglist) {
try {
processOFMessage(ofm);
- }
- catch (Exception ex) {
+ } catch (Exception ex) {
// We are the last handler in the stream, so run the
// exception through the channel again by passing in
// ctx.getChannel().
@@ -500,78 +503,78 @@
OFSwitchImpl.flush_all();
}
}
-
+
/**
* Process the request for the switch description
*/
- @LogMessageDoc(level="ERROR",
- message="Exception in reading description " +
+ @LogMessageDoc(level = "ERROR",
+ message = "Exception in reading description " +
" during handshake {exception}",
- explanation="Could not process the switch description string",
- recommendation=LogMessageDoc.CHECK_SWITCH)
+ explanation = "Could not process the switch description string",
+ recommendation = LogMessageDoc.CHECK_SWITCH)
void processSwitchDescReply() {
try {
// Read description, if it has been updated
@SuppressWarnings("unchecked")
Future<List<OFStatistics>> desc_future =
- (Future<List<OFStatistics>>)sw.
- getAttribute(IOFSwitch.SWITCH_DESCRIPTION_FUTURE);
- List<OFStatistics> values =
+ (Future<List<OFStatistics>>) sw.
+ getAttribute(IOFSwitch.SWITCH_DESCRIPTION_FUTURE);
+ List<OFStatistics> values =
desc_future.get(0, TimeUnit.MILLISECONDS);
if (values != null) {
- OFDescriptionStatistics description =
+ OFDescriptionStatistics description =
new OFDescriptionStatistics();
- ChannelBuffer data =
+ ChannelBuffer data =
ChannelBuffers.buffer(description.getLength());
for (OFStatistics f : values) {
f.writeTo(data);
description.readFrom(data);
break; // SHOULD be a list of length 1
}
- sw.setAttribute(IOFSwitch.SWITCH_DESCRIPTION_DATA,
- description);
+ sw.setAttribute(IOFSwitch.SWITCH_DESCRIPTION_DATA,
+ description);
sw.setSwitchProperties(description);
data = null;
}
-
+
sw.removeAttribute(IOFSwitch.SWITCH_DESCRIPTION_FUTURE);
state.hasDescription = true;
checkSwitchReady();
- }
- catch (InterruptedException ex) {
+ } catch (InterruptedException ex) {
// Ignore
- }
- catch (TimeoutException ex) {
+ } catch (TimeoutException ex) {
// Ignore
} catch (Exception ex) {
- log.error("Exception in reading description " +
- " during handshake", ex);
+ log.error("Exception in reading description " +
+ " during handshake", ex);
}
}
/**
* Send initial switch setup information that we need before adding
* the switch
+ *
* @throws IOException
*/
void sendHelloConfiguration() throws IOException {
// Send initial Features Request
- log.debug("Sending FEATURES_REQUEST to {}", sw);
+ log.debug("Sending FEATURES_REQUEST to {}", sw);
sw.write(factory.getMessage(OFType.FEATURES_REQUEST), null);
}
-
+
/**
* Send the configuration requests we can only do after we have
* the features reply
+ *
* @throws IOException
*/
void sendFeatureReplyConfiguration() throws IOException {
- log.debug("Sending CONFIG_REQUEST to {}", sw);
+ log.debug("Sending CONFIG_REQUEST to {}", sw);
// Ensure we receive the full packet via PacketIn
OFSetConfig config = (OFSetConfig) factory
.getMessage(OFType.SET_CONFIG);
config.setMissSendLength((short) 0xffff)
- .setLengthU(OFSwitchConfig.MINIMUM_LENGTH);
+ .setLengthU(OFSwitchConfig.MINIMUM_LENGTH);
sw.write(config, null);
sw.write(factory.getMessage(OFType.GET_CONFIG_REQUEST),
null);
@@ -580,22 +583,23 @@
OFStatisticsRequest req = new OFStatisticsRequest();
req.setStatisticType(OFStatisticsType.DESC);
req.setLengthU(req.getLengthU());
- Future<List<OFStatistics>> dfuture =
+ Future<List<OFStatistics>> dfuture =
sw.getStatistics(req);
sw.setAttribute(IOFSwitch.SWITCH_DESCRIPTION_FUTURE,
dfuture);
}
-
- volatile Boolean controlRequested = Boolean.FALSE;
+
+ volatile Boolean controlRequested = Boolean.FALSE;
+
protected void checkSwitchReady() {
if (state.hsState == HandshakeState.FEATURES_REPLY &&
state.hasDescription && state.hasGetConfigReply) {
-
+
state.hsState = HandshakeState.READY;
log.debug("Handshake with {} complete", sw);
-
- synchronized(roleChanger) {
+
+ synchronized (roleChanger) {
// We need to keep track of all of the switches that are connected
// to the controller, in any role, so that we can later send the
// role request messages when the controller role changes.
@@ -604,26 +608,25 @@
// we were able to add this new switch to connectedSwitches
// *and* send the current role to the new switch.
connectedSwitches.add(sw);
-
+
if (role != null) {
- //Put the switch in SLAVE mode until we know we have control
- log.debug("Setting new switch {} to SLAVE", sw.getStringId());
- Collection<OFSwitchImpl> swList = new ArrayList<OFSwitchImpl>(1);
- swList.add(sw);
- roleChanger.submitRequest(swList, Role.SLAVE);
-
- //Request control of the switch from the global registry
- try {
- controlRequested = Boolean.TRUE;
- registryService.requestControl(sw.getId(),
- new RoleChangeCallback());
- } catch (RegistryException e) {
- log.debug("Registry error: {}", e.getMessage());
- controlRequested = Boolean.FALSE;
- }
-
-
-
+ //Put the switch in SLAVE mode until we know we have control
+ log.debug("Setting new switch {} to SLAVE", sw.getStringId());
+ Collection<OFSwitchImpl> swList = new ArrayList<OFSwitchImpl>(1);
+ swList.add(sw);
+ roleChanger.submitRequest(swList, Role.SLAVE);
+
+ //Request control of the switch from the global registry
+ try {
+ controlRequested = Boolean.TRUE;
+ registryService.requestControl(sw.getId(),
+ new RoleChangeCallback());
+ } catch (RegistryException e) {
+ log.debug("Registry error: {}", e.getMessage());
+ controlRequested = Boolean.FALSE;
+ }
+
+
// Send a role request if role support is enabled for the controller
// This is a probe that we'll use to determine if the switch
// actually supports the role request message. If it does we'll
@@ -639,11 +642,10 @@
swList.add(sw);
roleChanger.submitRequest(swList, role);
*/
- }
- else {
+ } else {
// Role supported not enabled on controller (for now)
// automatically promote switch to active state.
- log.debug("This controller's role is {}, " +
+ log.debug("This controller's role is {}, " +
"not sending role request msg to {}",
role, sw);
// Need to clear FlowMods before we add the switch
@@ -654,20 +656,20 @@
}
}
if (!controlRequested) {
- // yield to allow other thread(s) to release control
- try {
- Thread.sleep(10);
- } catch (InterruptedException e) {
- // Ignore interruptions
- }
- // safer to bounce the switch to reconnect here than proceeding further
- log.debug("Closing {} because we weren't able to request control " +
- "successfully" + sw);
- sw.channel.close();
+ // yield to allow other thread(s) to release control
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) {
+ // Ignore interruptions
+ }
+ // safer to bounce the switch to reconnect here than proceeding further
+ log.debug("Closing {} because we weren't able to request control " +
+ "successfully" + sw);
+ sw.channel.close();
}
}
}
-
+
/* Handle a role reply message we received from the switch. Since
* netty serializes message dispatch we don't need to synchronize
* against other receive operations from the same switch, so no need
@@ -679,13 +681,13 @@
* removedSwitch notification):1
*
*/
- @LogMessageDoc(level="ERROR",
- message="Invalid role value in role reply message",
- explanation="Was unable to set the HA role (master or slave) " +
+ @LogMessageDoc(level = "ERROR",
+ message = "Invalid role value in role reply message",
+ explanation = "Was unable to set the HA role (master or slave) " +
"for the controller.",
- recommendation=LogMessageDoc.CHECK_CONTROLLER)
+ recommendation = LogMessageDoc.CHECK_CONTROLLER)
protected void handleRoleReplyMessage(OFVendor vendorMessage,
- OFRoleReplyVendorData roleReplyVendorData) {
+ OFRoleReplyVendorData roleReplyVendorData) {
// Map from the role code in the message to our role enum
int nxRole = roleReplyVendorData.getRole();
Role role = null;
@@ -704,20 +706,20 @@
sw.getChannel().close();
return;
}
-
+
log.debug("Handling role reply for role {} from {}. " +
- "Controller's role is {} ",
- new Object[] { role, sw, Controller.this.role}
- );
-
+ "Controller's role is {} ",
+ new Object[]{role, sw, Controller.this.role}
+ );
+
sw.deliverRoleReply(vendorMessage.getXid(), role);
-
+
boolean isActive = activeSwitches.containsKey(sw.getId());
if (!isActive && sw.isActive()) {
// Transition from SLAVE to MASTER.
-
- if (!state.firstRoleReplyReceived ||
- getAlwaysClearFlowsOnSwAdd()) {
+
+ if (!state.firstRoleReplyReceived ||
+ getAlwaysClearFlowsOnSwAdd()) {
// This is the first role-reply message we receive from
// this switch or roles were disabled when the switch
// connected:
@@ -740,14 +742,14 @@
// flushed. Not sure how to handle that case though...
sw.clearAllFlowMods();
log.debug("First role reply from master switch {}, " +
- "clear FlowTable to active switch list",
- HexString.toHexString(sw.getId()));
+ "clear FlowTable to active switch list",
+ HexString.toHexString(sw.getId()));
}
-
+
// Some switches don't seem to update us with port
// status messages while in slave role.
//readSwitchPortStateFromStorage(sw);
-
+
// Only add the switch to the active switch list if
// we're not in the slave role. Note that if the role
// attribute is null, then that means that the switch
@@ -756,17 +758,16 @@
// switch should be included in the active switch list.
addSwitch(sw);
log.debug("Added master switch {} to active switch list",
- HexString.toHexString(sw.getId()));
+ HexString.toHexString(sw.getId()));
- }
- else if (isActive && !sw.isActive()) {
+ } else if (isActive && !sw.isActive()) {
// Transition from MASTER to SLAVE: remove switch
// from active switch list.
log.debug("Removed slave switch {} from active switch" +
- " list", HexString.toHexString(sw.getId()));
+ " list", HexString.toHexString(sw.getId()));
removeSwitch(sw);
}
-
+
// Indicate that we have received a role reply message.
state.firstRoleReplyReceived = true;
}
@@ -777,18 +778,18 @@
switch (vendor) {
case OFNiciraVendorData.NX_VENDOR_ID:
OFNiciraVendorData niciraVendorData =
- (OFNiciraVendorData)vendorMessage.getVendorData();
+ (OFNiciraVendorData) vendorMessage.getVendorData();
int dataType = niciraVendorData.getDataType();
switch (dataType) {
case OFRoleReplyVendorData.NXT_ROLE_REPLY:
OFRoleReplyVendorData roleReplyVendorData =
(OFRoleReplyVendorData) niciraVendorData;
- handleRoleReplyMessage(vendorMessage,
- roleReplyVendorData);
+ handleRoleReplyMessage(vendorMessage,
+ roleReplyVendorData);
break;
default:
log.warn("Unhandled Nicira VENDOR message; " +
- "data type = {}", dataType);
+ "data type = {}", dataType);
break;
}
break;
@@ -796,54 +797,55 @@
log.warn("Unhandled VENDOR message; vendor id = {}", vendor);
break;
}
-
+
return shouldHandleMessage;
}
/**
* Dispatch an Openflow message from a switch to the appropriate
* handler.
+ *
* @param m The message to process
* @throws IOException
- * @throws SwitchStateException
+ * @throws SwitchStateException
*/
@LogMessageDocs({
- @LogMessageDoc(level="WARN",
- message="Config Reply from {switch} has " +
- "miss length set to {length}",
- explanation="The controller requires that the switch " +
- "use a miss length of 0xffff for correct " +
- "function",
- recommendation="Use a different switch to ensure " +
- "correct function"),
- @LogMessageDoc(level="WARN",
- message="Received ERROR from sw {switch} that "
- +"indicates roles are not supported "
- +"but we have received a valid "
- +"role reply earlier",
- explanation="The switch sent a confusing message to the" +
- "controller")
+ @LogMessageDoc(level = "WARN",
+ message = "Config Reply from {switch} has " +
+ "miss length set to {length}",
+ explanation = "The controller requires that the switch " +
+ "use a miss length of 0xffff for correct " +
+ "function",
+ recommendation = "Use a different switch to ensure " +
+ "correct function"),
+ @LogMessageDoc(level = "WARN",
+ message = "Received ERROR from sw {switch} that "
+ + "indicates roles are not supported "
+ + "but we have received a valid "
+ + "role reply earlier",
+ explanation = "The switch sent a confusing message to the" +
+ "controller")
})
protected void processOFMessage(OFMessage m)
throws IOException, SwitchStateException {
boolean shouldHandleMessage = false;
-
+
switch (m.getType()) {
case HELLO:
if (log.isTraceEnabled())
log.trace("HELLO from {}", sw);
-
+
if (state.hsState.equals(HandshakeState.START)) {
state.hsState = HandshakeState.HELLO;
sendHelloConfiguration();
} else {
- throw new SwitchStateException("Unexpected HELLO from "
- + sw);
+ throw new SwitchStateException("Unexpected HELLO from "
+ + sw);
}
break;
case ECHO_REQUEST:
OFEchoReply reply =
- (OFEchoReply) factory.getMessage(OFType.ECHO_REPLY);
+ (OFEchoReply) factory.getMessage(OFType.ECHO_REPLY);
reply.setXid(m.getXid());
sw.write(reply, null);
break;
@@ -852,7 +854,7 @@
case FEATURES_REPLY:
if (log.isTraceEnabled())
log.trace("Features Reply from {}", sw);
-
+
sw.setFeaturesReply((OFFeaturesReply) m);
if (state.hsState.equals(HandshakeState.HELLO)) {
sendFeatureReplyConfiguration();
@@ -870,28 +872,28 @@
case GET_CONFIG_REPLY:
if (log.isTraceEnabled())
log.trace("Get config reply from {}", sw);
-
+
if (!state.hsState.equals(HandshakeState.FEATURES_REPLY)) {
String em = "Unexpected GET_CONFIG_REPLY from " + sw;
throw new SwitchStateException(em);
}
OFGetConfigReply cr = (OFGetConfigReply) m;
- if (cr.getMissSendLength() == (short)0xffff) {
- log.trace("Config Reply from {} confirms " +
- "miss length set to 0xffff", sw);
+ if (cr.getMissSendLength() == (short) 0xffff) {
+ log.trace("Config Reply from {} confirms " +
+ "miss length set to 0xffff", sw);
} else {
log.warn("Config Reply from {} has " +
- "miss length set to {}",
- sw, cr.getMissSendLength() & 0xffff);
+ "miss length set to {}",
+ sw, cr.getMissSendLength() & 0xffff);
}
state.hasGetConfigReply = true;
checkSwitchReady();
break;
case VENDOR:
- shouldHandleMessage = handleVendorMessage((OFVendor)m);
+ shouldHandleMessage = handleVendorMessage((OFVendor) m);
break;
case ERROR:
- log.debug("Recieved ERROR message from switch {}: {}", sw, m);
+ log.debug("Recieved ERROR message from switch {}: {}", sw, m);
// TODO: we need better error handling. Especially for
// request/reply style message (stats, roles) we should have
// a unified way to lookup the xid in the error message.
@@ -903,8 +905,8 @@
// i.e., check only whether the first request fails?
if (sw.checkFirstPendingRoleRequestXid(error.getXid())) {
boolean isBadVendorError =
- (error.getErrorType() == OFError.OFErrorType.
- OFPET_BAD_REQUEST.getValue());
+ (error.getErrorType() == OFError.OFErrorType.
+ OFPET_BAD_REQUEST.getValue());
// We expect to receive a bad vendor error when
// we're connected to a switch that doesn't support
// the Nicira vendor extensions (i.e. not OVS or
@@ -915,31 +917,30 @@
// is not a spurious error
shouldLogError = !isBadVendorError;
if (isBadVendorError) {
- log.debug("Handling bad vendor error for {}", sw);
+ log.debug("Handling bad vendor error for {}", sw);
if (state.firstRoleReplyReceived && (role != null)) {
log.warn("Received ERROR from sw {} that "
- +"indicates roles are not supported "
- +"but we have received a valid "
- +"role reply earlier", sw);
+ + "indicates roles are not supported "
+ + "but we have received a valid "
+ + "role reply earlier", sw);
}
state.firstRoleReplyReceived = true;
- Role requestedRole =
- sw.deliverRoleRequestNotSupportedEx(error.getXid());
- synchronized(roleChanger) {
- if (sw.role == null && Controller.this.role==Role.SLAVE) {
- //This will now never happen. The Controller's role
- //is now never SLAVE, always MASTER.
+ Role requestedRole =
+ sw.deliverRoleRequestNotSupportedEx(error.getXid());
+ synchronized (roleChanger) {
+ if (sw.role == null && Controller.this.role == Role.SLAVE) {
+ //This will now never happen. The Controller's role
+ //is now never SLAVE, always MASTER.
// the switch doesn't understand role request
// messages and the current controller role is
// slave. We need to disconnect the switch.
// @see RoleChanger for rationale
- log.warn("Closing {} channel because controller's role " +
- "is SLAVE", sw);
+ log.warn("Closing {} channel because controller's role " +
+ "is SLAVE", sw);
sw.getChannel().close();
- }
- else if (sw.role == null && requestedRole == Role.MASTER) {
- log.debug("Adding switch {} because we got an error" +
- " returned from a MASTER role request", sw);
+ } else if (sw.role == null && requestedRole == Role.MASTER) {
+ log.debug("Adding switch {} because we got an error" +
+ " returned from a MASTER role request", sw);
// Controller's role is master: add to
// active
// TODO: check if clearing flow table is
@@ -952,8 +953,7 @@
addSwitch(sw);
}
}
- }
- else {
+ } else {
// TODO: Is this the right thing to do if we receive
// some other error besides a bad vendor error?
// Presumably that means the switch did actually
@@ -972,8 +972,8 @@
// to make sure that the switch eventually accepts one
// of our requests or disconnect the switch. This feels
// cumbersome.
- log.debug("Closing {} channel because we recieved an " +
- "error other than BAD_VENDOR", sw);
+ log.debug("Closing {} channel because we recieved an " +
+ "error other than BAD_VENDOR", sw);
sw.getChannel().close();
}
}
@@ -984,8 +984,8 @@
logError(sw, error);
break;
case STATS_REPLY:
- if (state.hsState.ordinal() <
- HandshakeState.FEATURES_REPLY.ordinal()) {
+ if (state.hsState.ordinal() <
+ HandshakeState.FEATURES_REPLY.ordinal()) {
String em = "Unexpected STATS_REPLY from " + sw;
throw new SwitchStateException(em);
}
@@ -999,9 +999,9 @@
// the slave role, but we only want to update storage if
// we're the master (or equal).
boolean updateStorage = state.hsState.
- equals(HandshakeState.READY) &&
- (sw.getRole() != Role.SLAVE);
- handlePortStatusMessage(sw, (OFPortStatus)m, updateStorage);
+ equals(HandshakeState.READY) &&
+ (sw.getRole() != Role.SLAVE);
+ handlePortStatusMessage(sw, (OFPortStatus) m, updateStorage);
shouldHandleMessage = true;
break;
@@ -1009,15 +1009,15 @@
shouldHandleMessage = true;
break;
}
-
+
if (shouldHandleMessage) {
sw.getListenerReadLock().lock();
try {
if (sw.isConnected()) {
if (!state.hsState.equals(HandshakeState.READY)) {
- log.debug("Ignoring message type {} received " +
- "from switch {} before switch is " +
- "fully configured.", m.getType(), sw);
+ log.debug("Ignoring message type {} received " +
+ "from switch {} before switch is " +
+ "fully configured.", m.getType(), sw);
}
// Check if the controller is in the slave role for the
// switch. If it is, then don't dispatch the message to
@@ -1043,8 +1043,7 @@
handleMessage(sw, m, null);
}
}
- }
- finally {
+ } finally {
sw.getListenerReadLock().unlock();
}
}
@@ -1054,41 +1053,41 @@
// ****************
// Message handlers
// ****************
-
+
protected void handlePortStatusMessage(IOFSwitch sw,
OFPortStatus m,
boolean updateStorage) {
short portNumber = m.getDesc().getPortNumber();
OFPhysicalPort port = m.getDesc();
- if (m.getReason() == (byte)OFPortReason.OFPPR_MODIFY.ordinal()) {
- boolean portDown = ((OFPortConfig.OFPPC_PORT_DOWN.getValue() & port.getConfig()) > 0) ||
- ((OFPortState.OFPPS_LINK_DOWN.getValue() & port.getState()) > 0);
+ if (m.getReason() == (byte) OFPortReason.OFPPR_MODIFY.ordinal()) {
+ boolean portDown = ((OFPortConfig.OFPPC_PORT_DOWN.getValue() & port.getConfig()) > 0) ||
+ ((OFPortState.OFPPS_LINK_DOWN.getValue() & port.getState()) > 0);
sw.setPort(port);
- if (!portDown) {
- SwitchUpdate update = new SwitchUpdate(sw, port, SwitchUpdateType.PORTADDED);
- try {
- this.updates.put(update);
- } catch (InterruptedException e) {
- log.error("Failure adding update to queue", e);
- }
- } else {
- SwitchUpdate update = new SwitchUpdate(sw, port, SwitchUpdateType.PORTREMOVED);
- try {
- this.updates.put(update);
- } catch (InterruptedException e) {
- log.error("Failure adding update to queue", e);
- }
- }
+ if (!portDown) {
+ SwitchUpdate update = new SwitchUpdate(sw, port, SwitchUpdateType.PORTADDED);
+ try {
+ this.updates.put(update);
+ } catch (InterruptedException e) {
+ log.error("Failure adding update to queue", e);
+ }
+ } else {
+ SwitchUpdate update = new SwitchUpdate(sw, port, SwitchUpdateType.PORTREMOVED);
+ try {
+ this.updates.put(update);
+ } catch (InterruptedException e) {
+ log.error("Failure adding update to queue", e);
+ }
+ }
//if (updateStorage)
- //updatePortInfo(sw, port);
+ //updatePortInfo(sw, port);
log.debug("Port #{} modified for {}", portNumber, sw);
- } else if (m.getReason() == (byte)OFPortReason.OFPPR_ADD.ordinal()) {
- // XXX Workaround to prevent race condition where a link is detected
- // and attempted to be written to the database before the port is in
- // the database. We now suppress link discovery on ports until we're
- // sure they're in the database.
- linkDiscovery.AddToSuppressLLDPs(sw.getId(), port.getPortNumber());
-
+ } else if (m.getReason() == (byte) OFPortReason.OFPPR_ADD.ordinal()) {
+ // XXX Workaround to prevent race condition where a link is detected
+ // and attempted to be written to the database before the port is in
+ // the database. We now suppress link discovery on ports until we're
+ // sure they're in the database.
+ linkDiscovery.AddToSuppressLLDPs(sw.getId(), port.getPortNumber());
+
sw.setPort(port);
SwitchUpdate update = new SwitchUpdate(sw, port, SwitchUpdateType.PORTADDED);
try {
@@ -1097,10 +1096,10 @@
log.error("Failure adding update to queue", e);
}
//if (updateStorage)
- //updatePortInfo(sw, port);
+ //updatePortInfo(sw, port);
log.debug("Port #{} added for {}", portNumber, sw);
- } else if (m.getReason() ==
- (byte)OFPortReason.OFPPR_DELETE.ordinal()) {
+ } else if (m.getReason() ==
+ (byte) OFPortReason.OFPPR_DELETE.ordinal()) {
sw.deletePort(portNumber);
SwitchUpdate update = new SwitchUpdate(sw, port, SwitchUpdateType.PORTREMOVED);
try {
@@ -1109,7 +1108,7 @@
log.error("Failure adding update to queue", e);
}
//if (updateStorage)
- //removePortInfo(sw, portNumber);
+ //removePortInfo(sw, portNumber);
log.debug("Port #{} deleted for {}", portNumber, sw);
}
SwitchUpdate update = new SwitchUpdate(sw, SwitchUpdateType.PORTCHANGED);
@@ -1119,20 +1118,21 @@
log.error("Failure adding update to queue", e);
}
}
-
+
/**
* flcontext_cache - Keep a thread local stack of contexts
*/
protected static final ThreadLocal<Stack<FloodlightContext>> flcontext_cache =
- new ThreadLocal <Stack<FloodlightContext>> () {
- @Override
- protected Stack<FloodlightContext> initialValue() {
- return new Stack<FloodlightContext>();
- }
- };
+ new ThreadLocal<Stack<FloodlightContext>>() {
+ @Override
+ protected Stack<FloodlightContext> initialValue() {
+ return new Stack<FloodlightContext>();
+ }
+ };
/**
* flcontext_alloc - pop a context off the stack, if required create a new one
+ *
* @return FloodlightContext
*/
protected static FloodlightContext flcontext_alloc() {
@@ -1140,8 +1140,7 @@
if (flcontext_cache.get().empty()) {
flcontext = new FloodlightContext();
- }
- else {
+ } else {
flcontext = flcontext_cache.get().pop();
}
@@ -1150,6 +1149,7 @@
/**
* flcontext_free - Free the context to the current thread
+ *
* @param flcontext
*/
protected void flcontext_free(FloodlightContext flcontext) {
@@ -1159,23 +1159,24 @@
/**
* Handle replies to certain OFMessages, and pass others off to listeners
- * @param sw The switch for the message
- * @param m The message
+ *
+ * @param sw The switch for the message
+ * @param m The message
* @param bContext The floodlight context. If null then floodlight context would
- * be allocated in this function
+ * be allocated in this function
* @throws IOException
*/
@LogMessageDocs({
- @LogMessageDoc(level="ERROR",
- message="Ignoring PacketIn (Xid = {xid}) because the data" +
- " field is empty.",
- explanation="The switch sent an improperly-formatted PacketIn" +
- " message",
- recommendation=LogMessageDoc.CHECK_SWITCH),
- @LogMessageDoc(level="WARN",
- message="Unhandled OF Message: {} from {}",
- explanation="The switch sent a message not handled by " +
- "the controller")
+ @LogMessageDoc(level = "ERROR",
+ message = "Ignoring PacketIn (Xid = {xid}) because the data" +
+ " field is empty.",
+ explanation = "The switch sent an improperly-formatted PacketIn" +
+ " message",
+ recommendation = LogMessageDoc.CHECK_SWITCH),
+ @LogMessageDoc(level = "WARN",
+ message = "Unhandled OF Message: {} from {}",
+ explanation = "The switch sent a message not handled by " +
+ "the controller")
})
protected void handleMessage(IOFSwitch sw, OFMessage m,
FloodlightContext bContext)
@@ -1184,14 +1185,14 @@
switch (m.getType()) {
case PACKET_IN:
- OFPacketIn pi = (OFPacketIn)m;
-
+ OFPacketIn pi = (OFPacketIn) m;
+
if (pi.getPacketData().length <= 0) {
- log.error("Ignoring PacketIn (Xid = " + pi.getXid() +
- ") because the data field is empty.");
+ log.error("Ignoring PacketIn (Xid = " + pi.getXid() +
+ ") because the data field is empty.");
return;
}
-
+
if (Controller.ALWAYS_DECODE_ETH) {
eth = new Ethernet();
eth.deserialize(pi.getPacketData(), 0,
@@ -1200,13 +1201,13 @@
// fall through to default case...
default:
-
+
List<IOFMessageListener> listeners = null;
if (messageListeners.containsKey(m.getType())) {
listeners = messageListeners.get(m.getType()).
getOrderedListeners();
}
-
+
FloodlightContext bc = null;
if (listeners != null) {
// Check if floodlight context is passed from the calling
@@ -1218,19 +1219,19 @@
bc = bContext;
}
if (eth != null) {
- IFloodlightProviderService.bcStore.put(bc,
- IFloodlightProviderService.CONTEXT_PI_PAYLOAD,
+ IFloodlightProviderService.bcStore.put(bc,
+ IFloodlightProviderService.CONTEXT_PI_PAYLOAD,
eth);
}
-
+
// Get the starting time (overall and per-component) of
// the processing chain for this packet if performance
// monitoring is turned on
-
+
Command cmd;
for (IOFMessageListener listener : listeners) {
if (listener instanceof IOFSwitchFilter) {
- if (!((IOFSwitchFilter)listener).isInterested(sw)) {
+ if (!((IOFSwitchFilter) listener).isInterested(sw)) {
continue;
}
}
@@ -1238,7 +1239,7 @@
cmd = listener.receive(sw, m, bc);
-
+
if (Command.STOP.equals(cmd)) {
break;
}
@@ -1247,24 +1248,25 @@
} else {
log.warn("Unhandled OF Message: {} from {}", m, sw);
}
-
+
if ((bContext == null) && (bc != null)) flcontext_free(bc);
}
}
-
+
/**
* Log an OpenFlow error message from a switch
- * @param sw The switch that sent the error
+ *
+ * @param sw The switch that sent the error
* @param error The error message
*/
- @LogMessageDoc(level="ERROR",
- message="Error {error type} {error code} from {switch}",
- explanation="The switch responded with an unexpected error" +
+ @LogMessageDoc(level = "ERROR",
+ message = "Error {error type} {error code} from {switch}",
+ explanation = "The switch responded with an unexpected error" +
"to an OpenFlow message from the controller",
- recommendation="This could indicate improper network operation. " +
+ recommendation = "This could indicate improper network operation. " +
"If the problem persists restarting the switch and " +
"controller may help."
- )
+ )
protected void logError(IOFSwitch sw, OFError error) {
int etint = 0xffff & error.getErrorType();
if (etint < 0 || etint >= OFErrorType.values().length) {
@@ -1273,71 +1275,72 @@
OFErrorType et = OFErrorType.values()[etint];
switch (et) {
case OFPET_HELLO_FAILED:
- OFHelloFailedCode hfc =
- OFHelloFailedCode.values()[0xffff & error.getErrorCode()];
- log.error("Error {} {} from {}", new Object[] {et, hfc, sw});
+ OFHelloFailedCode hfc =
+ OFHelloFailedCode.values()[0xffff & error.getErrorCode()];
+ log.error("Error {} {} from {}", new Object[]{et, hfc, sw});
break;
case OFPET_BAD_REQUEST:
- OFBadRequestCode brc =
- OFBadRequestCode.values()[0xffff & error.getErrorCode()];
- log.error("Error {} {} from {}", new Object[] {et, brc, sw});
+ OFBadRequestCode brc =
+ OFBadRequestCode.values()[0xffff & error.getErrorCode()];
+ log.error("Error {} {} from {}", new Object[]{et, brc, sw});
break;
case OFPET_BAD_ACTION:
OFBadActionCode bac =
- OFBadActionCode.values()[0xffff & error.getErrorCode()];
- log.error("Error {} {} from {}", new Object[] {et, bac, sw});
+ OFBadActionCode.values()[0xffff & error.getErrorCode()];
+ log.error("Error {} {} from {}", new Object[]{et, bac, sw});
break;
case OFPET_FLOW_MOD_FAILED:
OFFlowModFailedCode fmfc =
- OFFlowModFailedCode.values()[0xffff & error.getErrorCode()];
- log.error("Error {} {} from {}", new Object[] {et, fmfc, sw});
+ OFFlowModFailedCode.values()[0xffff & error.getErrorCode()];
+ log.error("Error {} {} from {}", new Object[]{et, fmfc, sw});
break;
case OFPET_PORT_MOD_FAILED:
OFPortModFailedCode pmfc =
- OFPortModFailedCode.values()[0xffff & error.getErrorCode()];
- log.error("Error {} {} from {}", new Object[] {et, pmfc, sw});
+ OFPortModFailedCode.values()[0xffff & error.getErrorCode()];
+ log.error("Error {} {} from {}", new Object[]{et, pmfc, sw});
break;
case OFPET_QUEUE_OP_FAILED:
OFQueueOpFailedCode qofc =
- OFQueueOpFailedCode.values()[0xffff & error.getErrorCode()];
- log.error("Error {} {} from {}", new Object[] {et, qofc, sw});
+ OFQueueOpFailedCode.values()[0xffff & error.getErrorCode()];
+ log.error("Error {} {} from {}", new Object[]{et, qofc, sw});
break;
default:
break;
}
}
-
+
/**
* Add a switch to the active switch list and call the switch listeners.
* This happens either when a switch first connects (and the controller is
* not in the slave role) or when the role of the controller changes from
* slave to master.
+ *
* @param sw the switch that has been added
*/
// TODO: need to rethink locking and the synchronous switch update.
// We can / should also handle duplicate DPIDs in connectedSwitches
- @LogMessageDoc(level="ERROR",
- message="New switch added {switch} for already-added switch {switch}",
- explanation="A switch with the same DPID as another switch " +
+ @LogMessageDoc(level = "ERROR",
+ message = "New switch added {switch} for already-added switch {switch}",
+ explanation = "A switch with the same DPID as another switch " +
"connected to the controller. This can be caused by " +
"multiple switches configured with the same DPID, or " +
"by a switch reconnected very quickly after " +
"disconnecting.",
- recommendation="If this happens repeatedly, it is likely there " +
+ recommendation = "If this happens repeatedly, it is likely there " +
"are switches with duplicate DPIDs on the network. " +
"Reconfigure the appropriate switches. If it happens " +
"very rarely, then it is likely this is a transient " +
"network problem that can be ignored."
- )
+ )
protected void addSwitch(IOFSwitch sw) {
- // XXX Workaround to prevent race condition where a link is detected
- // and attempted to be written to the database before the port is in
- // the database. We now suppress link discovery on ports until we're
- // sure they're in the database.
- for (OFPhysicalPort port : sw.getPorts()) {
- linkDiscovery.AddToSuppressLLDPs(sw.getId(), port.getPortNumber());
- }
-
+ // XXX Workaround to prevent race condition where a link is detected
+ // and attempted to be written to the database before the port is in
+ // the database. We now suppress link discovery on ports until we're
+ // sure they're in the database.
+ for (OFPhysicalPort port : sw.getPorts()) {
+ linkDiscovery.AddToSuppressLLDPs(sw.getId(), port.getPortNumber());
+ }
+
// TODO: is it safe to modify the HashMap without holding
// the old switch's lock?
OFSwitchImpl oldSw = (OFSwitchImpl) this.activeSwitches.put(sw.getId(), sw);
@@ -1346,20 +1349,20 @@
log.info("New add switch for pre-existing switch {}", sw);
return;
}
-
+
if (oldSw != null) {
oldSw.getListenerWriteLock().lock();
try {
log.error("New switch added {} for already-added switch {}",
- sw, oldSw);
+ sw, oldSw);
// Set the connected flag to false to suppress calling
// the listeners for this switch in processOFMessage
oldSw.setConnected(false);
-
+
oldSw.cancelAllStatisticsReplies();
-
+
//updateInactiveSwitchInfo(oldSw);
-
+
// we need to clean out old switch state definitively
// before adding the new switch
// FIXME: It seems not completely kosher to call the
@@ -1378,14 +1381,13 @@
// TODO: Figure out a way to handle this that avoids the
// spurious debug message.
log.debug("Closing {} because a new IOFSwitch got added " +
- "for this dpid", oldSw);
+ "for this dpid", oldSw);
oldSw.getChannel().close();
- }
- finally {
+ } finally {
oldSw.getListenerWriteLock().unlock();
}
}
-
+
//updateActiveSwitchInfo(sw);
SwitchUpdate update = new SwitchUpdate(sw, SwitchUpdateType.ADDED);
try {
@@ -1399,6 +1401,7 @@
* Remove a switch from the active switch list and call the switch listeners.
* This happens either when the switch is disconnected or when the
* controller's role for the switch changes from master to slave.
+ *
* @param sw the switch that has been removed
*/
protected void removeSwitch(IOFSwitch sw) {
@@ -1415,7 +1418,7 @@
// from slave controllers. Then we need to move this cancelation
// to switch disconnect
sw.cancelAllStatisticsReplies();
-
+
// FIXME: I think there's a race condition if we call updateInactiveSwitchInfo
// here if role support is enabled. In that case if the switch is being
// removed because we've been switched to being in the slave role, then I think
@@ -1424,7 +1427,7 @@
// updateInactiveSwitchInfo we may wipe out all of the state that was
// written out by the new master. Maybe need to revisit how we handle all
// of the switch state that's written to storage.
-
+
//updateInactiveSwitchInfo(sw);
SwitchUpdate update = new SwitchUpdate(sw, SwitchUpdateType.REMOVED);
try {
@@ -1433,16 +1436,16 @@
log.error("Failure adding update to queue", e);
}
}
-
+
// ***************
// IFloodlightProvider
// ***************
-
+
@Override
- public synchronized void addOFMessageListener(OFType type,
+ public synchronized void addOFMessageListener(OFType type,
IOFMessageListener listener) {
- ListenerDispatcher<OFType, IOFMessageListener> ldd =
- messageListeners.get(type);
+ ListenerDispatcher<OFType, IOFMessageListener> ldd =
+ messageListeners.get(type);
if (ldd == null) {
ldd = new ListenerDispatcher<OFType, IOFMessageListener>();
messageListeners.put(type, ldd);
@@ -1453,23 +1456,23 @@
@Override
public synchronized void removeOFMessageListener(OFType type,
IOFMessageListener listener) {
- ListenerDispatcher<OFType, IOFMessageListener> ldd =
- messageListeners.get(type);
+ ListenerDispatcher<OFType, IOFMessageListener> ldd =
+ messageListeners.get(type);
if (ldd != null) {
ldd.removeListener(listener);
}
}
-
+
private void logListeners() {
for (Map.Entry<OFType,
- ListenerDispatcher<OFType,
- IOFMessageListener>> entry
- : messageListeners.entrySet()) {
-
+ ListenerDispatcher<OFType,
+ IOFMessageListener>> entry
+ : messageListeners.entrySet()) {
+
OFType type = entry.getKey();
- ListenerDispatcher<OFType, IOFMessageListener> ldd =
+ ListenerDispatcher<OFType, IOFMessageListener> ldd =
entry.getValue();
-
+
StringBuffer sb = new StringBuffer();
sb.append("OFListeners for ");
sb.append(type);
@@ -1478,10 +1481,10 @@
sb.append(l.getName());
sb.append(",");
}
- log.debug(sb.toString());
+ log.debug(sb.toString());
}
}
-
+
public void removeOFMessageListeners(OFType type) {
messageListeners.remove(type);
}
@@ -1503,26 +1506,26 @@
@Override
public Map<OFType, List<IOFMessageListener>> getListeners() {
- Map<OFType, List<IOFMessageListener>> lers =
- new HashMap<OFType, List<IOFMessageListener>>();
- for(Entry<OFType, ListenerDispatcher<OFType, IOFMessageListener>> e :
- messageListeners.entrySet()) {
+ Map<OFType, List<IOFMessageListener>> lers =
+ new HashMap<OFType, List<IOFMessageListener>>();
+ for (Entry<OFType, ListenerDispatcher<OFType, IOFMessageListener>> e :
+ messageListeners.entrySet()) {
lers.put(e.getKey(), e.getValue().getOrderedListeners());
}
return Collections.unmodifiableMap(lers);
}
-
+
@Override
@LogMessageDocs({
- @LogMessageDoc(message="Failed to inject OFMessage {message} onto " +
- "a null switch",
- explanation="Failed to process a message because the switch " +
- " is no longer connected."),
- @LogMessageDoc(level="ERROR",
- message="Error reinjecting OFMessage on switch {switch}",
- explanation="An I/O error occured while attempting to " +
- "process an OpenFlow message",
- recommendation=LogMessageDoc.CHECK_SWITCH)
+ @LogMessageDoc(message = "Failed to inject OFMessage {message} onto " +
+ "a null switch",
+ explanation = "Failed to process a message because the switch " +
+ " is no longer connected."),
+ @LogMessageDoc(level = "ERROR",
+ message = "Error reinjecting OFMessage on switch {switch}",
+ explanation = "An I/O error occured while attempting to " +
+ "process an OpenFlow message",
+ recommendation = LogMessageDoc.CHECK_SWITCH)
})
public boolean injectOfMessage(IOFSwitch sw, OFMessage msg,
FloodlightContext bc) {
@@ -1530,7 +1533,7 @@
log.info("Failed to inject OFMessage {} onto a null switch", msg);
return false;
}
-
+
// FIXME: Do we need to be able to inject messages to switches
// where we're the slave controller (i.e. they're connected but
// not active)?
@@ -1541,32 +1544,32 @@
// through the normal netty event processing, including being
// handled
if (!activeSwitches.containsKey(sw.getId())) return false;
-
+
try {
// Pass Floodlight context to the handleMessages()
handleMessage(sw, msg, bc);
} catch (IOException e) {
- log.error("Error reinjecting OFMessage on switch {}",
- HexString.toHexString(sw.getId()));
+ log.error("Error reinjecting OFMessage on switch {}",
+ HexString.toHexString(sw.getId()));
return false;
}
return true;
}
@Override
- @LogMessageDoc(message="Calling System.exit",
- explanation="The controller is terminating")
+ @LogMessageDoc(message = "Calling System.exit",
+ explanation = "The controller is terminating")
public synchronized void terminate() {
log.info("Calling System.exit");
System.exit(1);
}
-
+
@Override
public boolean injectOfMessage(IOFSwitch sw, OFMessage msg) {
// call the overloaded version with floodlight context set to null
return injectOfMessage(sw, msg, null);
}
-
+
@Override
public void handleOutgoingMessage(IOFSwitch sw, OFMessage m,
FloodlightContext bc) {
@@ -1577,14 +1580,14 @@
List<IOFMessageListener> listeners = null;
if (messageListeners.containsKey(m.getType())) {
- listeners =
+ listeners =
messageListeners.get(m.getType()).getOrderedListeners();
}
-
- if (listeners != null) {
+
+ if (listeners != null) {
for (IOFMessageListener listener : listeners) {
if (listener instanceof IOFSwitchFilter) {
- if (!((IOFSwitchFilter)listener).isInterested(sw)) {
+ if (!((IOFSwitchFilter) listener).isInterested(sw)) {
continue;
}
}
@@ -1599,12 +1602,12 @@
public BasicFactory getOFMessageFactory() {
return factory;
}
-
+
@Override
public String getControllerId() {
return controllerId;
}
-
+
// **************
// Initialization
// **************
@@ -1625,18 +1628,19 @@
* it updates the current role in the file specified by the "role.path"
* file. Then if floodlight restarts for some reason it can get the
* correct current role of the controller from the file.
+ *
* @param configParams The config params for the FloodlightProvider service
* @return A valid role if role information is specified in the
- * config params, otherwise null
+ * config params, otherwise null
*/
@LogMessageDocs({
- @LogMessageDoc(message="Controller role set to {role}",
- explanation="Setting the initial HA role to "),
- @LogMessageDoc(level="ERROR",
- message="Invalid current role value: {role}",
- explanation="An invalid HA role value was read from the " +
+ @LogMessageDoc(message = "Controller role set to {role}",
+ explanation = "Setting the initial HA role to "),
+ @LogMessageDoc(level = "ERROR",
+ message = "Invalid current role value: {role}",
+ explanation = "An invalid HA role value was read from the " +
"properties file",
- recommendation=LogMessageDoc.CHECK_CONTROLLER)
+ recommendation = LogMessageDoc.CHECK_CONTROLLER)
})
protected Role getInitialRole(Map<String, String> configParams) {
Role role = null;
@@ -1648,8 +1652,7 @@
try {
properties.load(new FileInputStream(rolePath));
roleString = properties.getProperty("floodlight.role");
- }
- catch (IOException exc) {
+ } catch (IOException exc) {
// Don't treat it as an error if the file specified by the
// rolepath property doesn't exist. This lets us enable the
// HA mechanism by just creating/setting the floodlight.role
@@ -1658,60 +1661,60 @@
}
}
}
-
+
if (roleString != null) {
// Canonicalize the string to the form used for the enum constants
roleString = roleString.trim().toUpperCase();
try {
role = Role.valueOf(roleString);
- }
- catch (IllegalArgumentException exc) {
+ } catch (IllegalArgumentException exc) {
log.error("Invalid current role value: {}", roleString);
}
}
-
+
log.info("Controller role set to {}", role);
-
+
return role;
}
-
+
/**
* Tell controller that we're ready to accept switches loop
- * @throws IOException
+ *
+ * @throws IOException
*/
@LogMessageDocs({
- @LogMessageDoc(message="Listening for switch connections on {address}",
- explanation="The controller is ready and listening for new" +
- " switch connections"),
- @LogMessageDoc(message="Storage exception in controller " +
- "updates loop; terminating process",
- explanation=ERROR_DATABASE,
- recommendation=LogMessageDoc.CHECK_CONTROLLER),
- @LogMessageDoc(level="ERROR",
- message="Exception in controller updates loop",
- explanation="Failed to dispatch controller event",
- recommendation=LogMessageDoc.GENERIC_ACTION)
+ @LogMessageDoc(message = "Listening for switch connections on {address}",
+ explanation = "The controller is ready and listening for new" +
+ " switch connections"),
+ @LogMessageDoc(message = "Storage exception in controller " +
+ "updates loop; terminating process",
+ explanation = ERROR_DATABASE,
+ recommendation = LogMessageDoc.CHECK_CONTROLLER),
+ @LogMessageDoc(level = "ERROR",
+ message = "Exception in controller updates loop",
+ explanation = "Failed to dispatch controller event",
+ recommendation = LogMessageDoc.GENERIC_ACTION)
})
public void run() {
if (log.isDebugEnabled()) {
logListeners();
}
-
- try {
- final ServerBootstrap bootstrap = createServerBootStrap();
+
+ try {
+ final ServerBootstrap bootstrap = createServerBootStrap();
bootstrap.setOption("reuseAddr", true);
bootstrap.setOption("child.keepAlive", true);
bootstrap.setOption("child.tcpNoDelay", true);
bootstrap.setOption("child.sendBufferSize", Controller.SEND_BUFFER_SIZE);
- ChannelPipelineFactory pfact =
+ ChannelPipelineFactory pfact =
new OpenflowPipelineFactory(this, null);
bootstrap.setPipelineFactory(pfact);
InetSocketAddress sa = new InetSocketAddress(openFlowPort);
final ChannelGroup cg = new DefaultChannelGroup();
cg.add(bootstrap.bind(sa));
-
+
log.info("Listening for switch connections on {}", sa);
} catch (Exception e) {
throw new RuntimeException(e);
@@ -1743,7 +1746,7 @@
Executors.newCachedThreadPool(), workerThreads));
}
}
-
+
public void setConfigParams(Map<String, String> configParams) {
String ofPort = configParams.get("openflowport");
if (ofPort != null) {
@@ -1758,17 +1761,16 @@
String controllerId = configParams.get("controllerid");
if (controllerId != null) {
this.controllerId = controllerId;
+ } else {
+ //Try to get the hostname of the machine and use that for controller ID
+ try {
+ String hostname = java.net.InetAddress.getLocalHost().getHostName();
+ this.controllerId = hostname;
+ } catch (UnknownHostException e) {
+ // Can't get hostname, we'll just use the default
+ }
}
- else {
- //Try to get the hostname of the machine and use that for controller ID
- try {
- String hostname = java.net.InetAddress.getLocalHost().getHostName();
- this.controllerId = hostname;
- } catch (UnknownHostException e) {
- // Can't get hostname, we'll just use the default
- }
- }
-
+
log.debug("ControllerId set to {}", this.controllerId);
}
@@ -1787,9 +1789,9 @@
new OFBasicVendorDataType(
OFRoleReplyVendorData.NXT_ROLE_REPLY,
OFRoleReplyVendorData.getInstantiable());
- niciraVendorId.registerVendorDataType(roleReplyVendorData);
+ niciraVendorId.registerVendorDataType(roleReplyVendorData);
}
-
+
/**
* Initialize internal data structures
*/
@@ -1797,9 +1799,9 @@
// These data structures are initialized here because other
// module's startUp() might be called before ours
this.messageListeners =
- new ConcurrentHashMap<OFType,
- ListenerDispatcher<OFType,
- IOFMessageListener>>();
+ new ConcurrentHashMap<OFType,
+ ListenerDispatcher<OFType,
+ IOFMessageListener>>();
this.switchListeners = new CopyOnWriteArraySet<IOFSwitchListener>();
this.activeSwitches = new ConcurrentHashMap<Long, IOFSwitch>();
this.connectedSwitches = new HashSet<OFSwitchImpl>();
@@ -1813,33 +1815,33 @@
initVendorMessages();
this.systemStartTime = System.currentTimeMillis();
}
-
+
/**
* Startup all of the controller's components
*/
- @LogMessageDoc(message="Waiting for storage source",
- explanation="The system database is not yet ready",
- recommendation="If this message persists, this indicates " +
- "that the system database has failed to start. " +
- LogMessageDoc.CHECK_CONTROLLER)
+ @LogMessageDoc(message = "Waiting for storage source",
+ explanation = "The system database is not yet ready",
+ recommendation = "If this message persists, this indicates " +
+ "that the system database has failed to start. " +
+ LogMessageDoc.CHECK_CONTROLLER)
public void startupComponents() {
- try {
- registryService.registerController(controllerId);
- } catch (RegistryException e) {
- log.warn("Registry service error: {}", e.getMessage());
- }
-
+ try {
+ registryService.registerController(controllerId);
+ } catch (RegistryException e) {
+ log.warn("Registry service error: {}", e.getMessage());
+ }
+
// Add our REST API
restApi.addRestletRoutable(new CoreWebRoutable());
}
-
+
@Override
public Map<String, String> getControllerNodeIPs() {
// We return a copy of the mapping so we can guarantee that
// the mapping return is the same as one that will be (or was)
// dispatched to IHAListeners
- HashMap<String,String> retval = new HashMap<String,String>();
- synchronized(controllerNodeIPsCache) {
+ HashMap<String, String> retval = new HashMap<String, String>();
+ synchronized (controllerNodeIPsCache) {
retval.putAll(controllerNodeIPsCache);
}
return retval;
@@ -1854,7 +1856,7 @@
public void setAlwaysClearFlowsOnSwAdd(boolean value) {
this.alwaysClearFlowsOnSwAdd = value;
}
-
+
public boolean getAlwaysClearFlowsOnSwAdd() {
return this.alwaysClearFlowsOnSwAdd;
}
diff --git a/src/main/java/net/floodlightcontroller/core/internal/HandshakeTimeoutException.java b/src/main/java/net/floodlightcontroller/core/internal/HandshakeTimeoutException.java
index 421ec1a..57fa279 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/HandshakeTimeoutException.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/HandshakeTimeoutException.java
@@ -1,25 +1,26 @@
/**
-* 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.
-**/
+ * 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.internal;
/**
- * Exception is thrown when the handshake fails to complete
+ * Exception is thrown when the handshake fails to complete
* before a specified time
+ *
* @author readams
*/
public class HandshakeTimeoutException extends Exception {
diff --git a/src/main/java/net/floodlightcontroller/core/internal/HandshakeTimeoutHandler.java b/src/main/java/net/floodlightcontroller/core/internal/HandshakeTimeoutHandler.java
index 6d3335f..d5950b4 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/HandshakeTimeoutHandler.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/HandshakeTimeoutHandler.java
@@ -1,19 +1,19 @@
/**
-* 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.
-**/
+ * 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.internal;
@@ -33,17 +33,17 @@
/**
* Trigger a timeout if a switch fails to complete handshake soon enough
*/
-public class HandshakeTimeoutHandler
- extends SimpleChannelUpstreamHandler
- implements ExternalResourceReleasable {
- static final HandshakeTimeoutException EXCEPTION =
+public class HandshakeTimeoutHandler
+ extends SimpleChannelUpstreamHandler
+ implements ExternalResourceReleasable {
+ static final HandshakeTimeoutException EXCEPTION =
new HandshakeTimeoutException();
-
+
final OFChannelState state;
final Timer timer;
final long timeoutNanos;
volatile Timeout timeout;
-
+
public HandshakeTimeoutHandler(OFChannelState state, Timer timer,
long timeoutSeconds) {
super();
@@ -52,17 +52,17 @@
this.timeoutNanos = TimeUnit.SECONDS.toNanos(timeoutSeconds);
}
-
+
@Override
public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
throws Exception {
if (timeoutNanos > 0) {
- timeout = timer.newTimeout(new HandshakeTimeoutTask(ctx),
- timeoutNanos, TimeUnit.NANOSECONDS);
+ timeout = timer.newTimeout(new HandshakeTimeoutTask(ctx),
+ timeoutNanos, TimeUnit.NANOSECONDS);
}
ctx.sendUpstream(e);
}
-
+
@Override
public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e)
throws Exception {
@@ -76,7 +76,7 @@
public void releaseExternalResources() {
timer.stop();
}
-
+
private final class HandshakeTimeoutTask implements TimerTask {
private final ChannelHandlerContext ctx;
diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFChannelState.java b/src/main/java/net/floodlightcontroller/core/internal/OFChannelState.java
index ad5a377..8130c0a 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/OFChannelState.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/OFChannelState.java
@@ -1,24 +1,25 @@
/**
-* 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.
-**/
+ * 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.internal;
/**
* Wrapper class to hold state for the OpenFlow switch connection
+ *
* @author readams
*/
class OFChannelState {
@@ -53,7 +54,7 @@
protected volatile HandshakeState hsState = HandshakeState.START;
protected boolean hasGetConfigReply = false;
protected boolean hasDescription = false;
-
+
// The firstRoleReplyRecevied flag indicates if we have received the
// first role reply message on this connection (in response to the
// role request sent after the handshake). If role support is disabled
diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFFeaturesReplyFuture.java b/src/main/java/net/floodlightcontroller/core/internal/OFFeaturesReplyFuture.java
index eca67bd..70ab58e 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/OFFeaturesReplyFuture.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/OFFeaturesReplyFuture.java
@@ -1,6 +1,6 @@
/**
* Copyright 2012, Big Switch Networks, Inc.
- *
+ *
* 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
@@ -28,7 +28,7 @@
/**
* A concrete implementation that handles asynchronously receiving
* OFFeaturesReply
- *
+ *
* @author Shudong Zhou
*/
public class OFFeaturesReplyFuture extends
@@ -37,13 +37,13 @@
protected volatile boolean finished;
public OFFeaturesReplyFuture(IThreadPoolService tp,
- IOFSwitch sw, int transactionId) {
+ IOFSwitch sw, int transactionId) {
super(tp, sw, OFType.FEATURES_REPLY, transactionId);
init();
}
public OFFeaturesReplyFuture(IThreadPoolService tp,
- IOFSwitch sw, int transactionId, long timeout, TimeUnit unit) {
+ IOFSwitch sw, int transactionId, long timeout, TimeUnit unit) {
super(tp, sw, OFType.FEATURES_REPLY, transactionId, timeout, unit);
init();
}
diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFMessageDecoder.java b/src/main/java/net/floodlightcontroller/core/internal/OFMessageDecoder.java
index 295e967..54fafd5 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/OFMessageDecoder.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/OFMessageDecoder.java
@@ -1,19 +1,19 @@
/**
-* 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.
-**/
+ * 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.internal;
@@ -30,12 +30,13 @@
/**
* Decode an openflow message from a Channel, for use in a netty
* pipeline
+ *
* @author readams
*/
public class OFMessageDecoder extends FrameDecoder {
OFMessageFactory factory = new BasicFactory();
-
+
@Override
protected Object decode(ChannelHandlerContext ctx, Channel channel,
ChannelBuffer buffer) throws Exception {
@@ -51,7 +52,7 @@
@Override
protected Object decodeLast(ChannelHandlerContext ctx, Channel channel,
- ChannelBuffer buffer) throws Exception {
+ ChannelBuffer buffer) throws Exception {
// This is not strictly needed atthis time. It is used to detect
// connection reset detection from netty (for debug)
return null;
diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFMessageEncoder.java b/src/main/java/net/floodlightcontroller/core/internal/OFMessageEncoder.java
index 6be5f9a..d61f17e 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/OFMessageEncoder.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/OFMessageEncoder.java
@@ -1,19 +1,19 @@
/**
-* 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.
-**/
+ * 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.internal;
@@ -29,6 +29,7 @@
/**
* Encode an openflow message for output into a ChannelBuffer, for use in a
* netty pipeline
+ *
* @author readams
*/
public class OFMessageEncoder extends OneToOneEncoder {
@@ -36,18 +37,19 @@
@Override
protected Object encode(ChannelHandlerContext ctx, Channel channel,
Object msg) throws Exception {
- if (!( msg instanceof List))
+ if (!(msg instanceof List))
return msg;
@SuppressWarnings("unchecked")
- List<OFMessage> msglist = (List<OFMessage>)msg;
+ List<OFMessage> msglist = (List<OFMessage>) msg;
int size = 0;
- for (OFMessage ofm : msglist) {
- size += ofm.getLengthU();
+ for (OFMessage ofm : msglist) {
+ size += ofm.getLengthU();
}
- ChannelBuffer buf = ChannelBuffers.buffer(size);;
- for (OFMessage ofm : msglist) {
+ ChannelBuffer buf = ChannelBuffers.buffer(size);
+ ;
+ for (OFMessage ofm : msglist) {
ofm.writeTo(buf);
}
return buf;
diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFMessageFuture.java b/src/main/java/net/floodlightcontroller/core/internal/OFMessageFuture.java
index 60b932f..bd8456f 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/OFMessageFuture.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/OFMessageFuture.java
@@ -1,19 +1,19 @@
/**
-* 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.
-**/
+ * 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.internal;
@@ -51,13 +51,13 @@
protected static final TimeUnit DEFAULT_TIMEOUT_UNIT = TimeUnit.SECONDS;
public OFMessageFuture(IThreadPoolService tp,
- IOFSwitch sw, OFType responseType, int transactionId) {
- this(tp, sw, responseType, transactionId,
- DEFAULT_TIMEOUT, DEFAULT_TIMEOUT_UNIT);
+ IOFSwitch sw, OFType responseType, int transactionId) {
+ this(tp, sw, responseType, transactionId,
+ DEFAULT_TIMEOUT, DEFAULT_TIMEOUT_UNIT);
}
public OFMessageFuture(IThreadPoolService tp,
- IOFSwitch sw, OFType responseType, int transactionId, long timeout, TimeUnit unit) {
+ IOFSwitch sw, OFType responseType, int transactionId, long timeout, TimeUnit unit) {
this.threadPool = tp;
this.canceled = false;
this.latch = new CountDownLatch(1);
@@ -80,7 +80,7 @@
this.timeoutTimer = null;
}
-
+
public void deliverFuture(IOFSwitch sw, OFMessage msg) {
if (transactionId == msg.getXid()) {
handleReply(sw, msg);
@@ -95,6 +95,7 @@
* Used to handle the specific expected message this Future was reigstered
* for, the specified msg parameter is guaranteed to match the type and
* transaction id specified.
+ *
* @param sw
* @param msg
* @return
@@ -106,6 +107,7 @@
* indicate when the future can deregister itself from receiving future
* messages, and when it is safe to return the results to any waiting
* threads.
+ *
* @return when this Future has completed its work
*/
protected abstract boolean isFinished();
diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFStatisticsFuture.java b/src/main/java/net/floodlightcontroller/core/internal/OFStatisticsFuture.java
index 4d3f733..4651c74 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/OFStatisticsFuture.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/OFStatisticsFuture.java
@@ -1,19 +1,19 @@
/**
-* 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.
-**/
+ * 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.internal;
@@ -31,7 +31,7 @@
/**
* A concrete implementation that handles asynchronously receiving OFStatistics
- *
+ *
* @author David Erickson (daviderickson@cs.stanford.edu)
*/
public class OFStatisticsFuture extends
@@ -40,13 +40,13 @@
protected volatile boolean finished;
public OFStatisticsFuture(IThreadPoolService tp,
- IOFSwitch sw, int transactionId) {
+ IOFSwitch sw, int transactionId) {
super(tp, sw, OFType.STATS_REPLY, transactionId);
init();
}
public OFStatisticsFuture(IThreadPoolService tp,
- IOFSwitch sw, int transactionId, long timeout, TimeUnit unit) {
+ IOFSwitch sw, int transactionId, long timeout, TimeUnit unit) {
super(tp, sw, OFType.STATS_REPLY, transactionId, timeout, unit);
init();
}
@@ -71,7 +71,7 @@
protected boolean isFinished() {
return finished;
}
-
+
@Override
protected void unRegister() {
super.unRegister();
diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java b/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java
index 3164381..96ddc7c 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java
@@ -1,19 +1,19 @@
/**
-* Copyright 2012, 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.
-**/
+ * Copyright 2012, 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.internal;
@@ -82,11 +82,11 @@
// exception that can then be handled by callers?
protected final static Logger log = LoggerFactory.getLogger(OFSwitchImpl.class);
- private static final String HA_CHECK_SWITCH =
+ private static final String HA_CHECK_SWITCH =
"Check the health of the indicated switch. If the problem " +
- "persists or occurs repeatedly, it likely indicates a defect " +
- "in the switch HA implementation.";
-
+ "persists or occurs repeatedly, it likely indicates a defect " +
+ "in the switch HA implementation.";
+
protected ConcurrentMap<Object, Object> attributes;
protected IFloodlightProviderService floodlightProvider;
protected IThreadPoolService threadPool;
@@ -104,9 +104,9 @@
// XXX: The OF spec doesn't specify if port names need to be unique but
// according it's always the case in practice.
protected ConcurrentHashMap<String, OFPhysicalPort> portsByName;
- protected Map<Integer,OFStatisticsFuture> statsFutureMap;
+ protected Map<Integer, OFStatisticsFuture> statsFutureMap;
protected Map<Integer, IOFMessageListener> iofMsgListenersMap;
- protected Map<Integer,OFFeaturesReplyFuture> featuresFutureMap;
+ protected Map<Integer, OFFeaturesReplyFuture> featuresFutureMap;
protected boolean connected;
protected Role role;
protected TimedCache<Long> timedCache;
@@ -114,16 +114,16 @@
protected ConcurrentMap<Short, Long> portBroadcastCacheHitMap;
/**
* When sending a role request message, the role request is added
- * to this queue. If a role reply is received this queue is checked to
+ * to this queue. If a role reply is received this queue is checked to
* verify that the reply matches the expected reply. We require in order
- * delivery of replies. That's why we use a Queue.
+ * delivery of replies. That's why we use a Queue.
* The RoleChanger uses a timeout to ensure we receive a timely reply.
- *
- * Need to synchronize on this instance if a request is sent, received,
- * checked.
+ * <p/>
+ * Need to synchronize on this instance if a request is sent, received,
+ * checked.
*/
protected LinkedList<PendingRoleRequestEntry> pendingRoleRequests;
-
+
/* Switch features from initial featuresReply */
protected int capabilities;
protected int buffers;
@@ -132,29 +132,30 @@
protected long datapathId;
public static IOFSwitchFeatures switchFeatures;
- protected static final ThreadLocal<Map<OFSwitchImpl,List<OFMessage>>> local_msg_buffer =
- new ThreadLocal<Map<OFSwitchImpl,List<OFMessage>>>() {
- @Override
- protected Map<OFSwitchImpl,List<OFMessage>> initialValue() {
- return new HashMap<OFSwitchImpl,List<OFMessage>>();
- }
- };
-
+ protected static final ThreadLocal<Map<OFSwitchImpl, List<OFMessage>>> local_msg_buffer =
+ new ThreadLocal<Map<OFSwitchImpl, List<OFMessage>>>() {
+ @Override
+ protected Map<OFSwitchImpl, List<OFMessage>> initialValue() {
+ return new HashMap<OFSwitchImpl, List<OFMessage>>();
+ }
+ };
+
// for managing our map sizes
- protected static final int MAX_MACS_PER_SWITCH = 1000;
-
+ protected static final int MAX_MACS_PER_SWITCH = 1000;
+
protected static class PendingRoleRequestEntry {
protected int xid;
protected Role role;
// cookie is used to identify the role "generation". roleChanger uses
protected long cookie;
+
public PendingRoleRequestEntry(int xid, Role role, long cookie) {
this.xid = xid;
this.role = role;
this.cookie = cookie;
}
}
-
+
public OFSwitchImpl() {
this.stringId = null;
this.attributes = new ConcurrentHashMap<Object, Object>();
@@ -164,21 +165,21 @@
this.portsByNumber = new ConcurrentHashMap<Short, OFPhysicalPort>();
this.portsByName = new ConcurrentHashMap<String, OFPhysicalPort>();
this.connected = true;
- this.statsFutureMap = new ConcurrentHashMap<Integer,OFStatisticsFuture>();
- this.featuresFutureMap = new ConcurrentHashMap<Integer,OFFeaturesReplyFuture>();
- this.iofMsgListenersMap = new ConcurrentHashMap<Integer,IOFMessageListener>();
+ this.statsFutureMap = new ConcurrentHashMap<Integer, OFStatisticsFuture>();
+ this.featuresFutureMap = new ConcurrentHashMap<Integer, OFFeaturesReplyFuture>();
+ this.iofMsgListenersMap = new ConcurrentHashMap<Integer, IOFMessageListener>();
this.role = null;
- this.timedCache = new TimedCache<Long>(100, 5*1000 ); // 5 seconds interval
+ this.timedCache = new TimedCache<Long>(100, 5 * 1000); // 5 seconds interval
this.listenerLock = new ReentrantReadWriteLock();
this.portBroadcastCacheHitMap = new ConcurrentHashMap<Short, Long>();
this.pendingRoleRequests = new LinkedList<OFSwitchImpl.PendingRoleRequestEntry>();
-
+
// Defaults properties for an ideal switch
this.setAttribute(PROP_FASTWILDCARDS, OFMatch.OFPFW_ALL);
this.setAttribute(PROP_SUPPORTS_OFPP_FLOOD, new Boolean(true));
this.setAttribute(PROP_SUPPORTS_OFPP_TABLE, new Boolean(true));
}
-
+
@Override
public Object getAttribute(String name) {
@@ -187,7 +188,7 @@
}
return null;
}
-
+
@Override
public void setAttribute(String name, Object value) {
this.attributes.put(name, value);
@@ -198,12 +199,12 @@
public Object removeAttribute(String name) {
return this.attributes.remove(name);
}
-
+
@Override
public boolean hasAttribute(String name) {
return this.attributes.containsKey(name);
}
-
+
@Override
@JsonIgnore
public Channel getChannel() {
@@ -214,10 +215,10 @@
public void setChannel(Channel channel) {
this.channel = channel;
}
-
+
@Override
public void write(OFMessage m, FloodlightContext bc) throws IOException {
- Map<OFSwitchImpl,List<OFMessage>> msg_buffer_map = local_msg_buffer.get();
+ Map<OFSwitchImpl, List<OFMessage>> msg_buffer_map = local_msg_buffer.get();
List<OFMessage> msg_buffer = msg_buffer_map.get(this);
if (msg_buffer == null) {
msg_buffer = new ArrayList<OFMessage>();
@@ -228,20 +229,20 @@
msg_buffer.add(m);
if ((msg_buffer.size() >= Controller.BATCH_MAX_SIZE) ||
- ((m.getType() != OFType.PACKET_OUT) && (m.getType() != OFType.FLOW_MOD))) {
+ ((m.getType() != OFType.PACKET_OUT) && (m.getType() != OFType.FLOW_MOD))) {
this.write(msg_buffer);
msg_buffer.clear();
}
}
@Override
- @LogMessageDoc(level="WARN",
- message="Sending OF message that modifies switch " +
- "state while in the slave role: {switch}",
- explanation="An application has sent a message to a switch " +
- "that is not valid when the switch is in a slave role",
- recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG)
- public void write(List<OFMessage> msglist,
+ @LogMessageDoc(level = "WARN",
+ message = "Sending OF message that modifies switch " +
+ "state while in the slave role: {switch}",
+ explanation = "An application has sent a message to a switch " +
+ "that is not valid when the switch is in a slave role",
+ recommendation = LogMessageDoc.REPORT_CONTROLLER_BUG)
+ public void write(List<OFMessage> msglist,
FloodlightContext bc) throws IOException {
for (OFMessage m : msglist) {
if (role == Role.SLAVE) {
@@ -250,8 +251,8 @@
case FLOW_MOD:
case PORT_MOD:
log.warn("Sending OF message that modifies switch " +
- "state while in the slave role: {}",
- m.getType().name());
+ "state while in the slave role: {}",
+ m.getType().name());
break;
default:
break;
@@ -265,7 +266,7 @@
public void write(List<OFMessage> msglist) throws IOException {
this.channel.write(msglist);
}
-
+
@Override
public void disconnectOutputStream() {
channel.close();
@@ -274,7 +275,7 @@
@Override
@JsonIgnore
public void setFeaturesReply(OFFeaturesReply featuresReply) {
- synchronized(portLock) {
+ synchronized (portLock) {
if (stringId == null) {
/* ports are updated via port status message, so we
* only fill in ports on initial connection.
@@ -303,7 +304,7 @@
}
return result;
}
-
+
@Override
@JsonIgnore
public Collection<Short> getEnabledPortNumbers() {
@@ -320,7 +321,7 @@
public OFPhysicalPort getPort(short portNumber) {
return portsByNumber.get(portNumber);
}
-
+
@Override
public OFPhysicalPort getPort(String portName) {
return portsByName.get(portName);
@@ -329,29 +330,29 @@
@Override
@JsonIgnore
public void setPort(OFPhysicalPort port) {
- synchronized(portLock) {
+ synchronized (portLock) {
portsByNumber.put(port.getPortNumber(), port);
portsByName.put(port.getName(), port);
}
}
-
+
@Override
@JsonProperty("ports")
public Collection<OFPhysicalPort> getPorts() {
return Collections.unmodifiableCollection(portsByNumber.values());
}
-
+
@Override
public void deletePort(short portNumber) {
- synchronized(portLock) {
+ synchronized (portLock) {
portsByName.remove(portsByNumber.get(portNumber).getName());
portsByNumber.remove(portNumber);
}
}
-
+
@Override
public void deletePort(String portName) {
- synchronized(portLock) {
+ synchronized (portLock) {
portsByNumber.remove(portsByName.get(portName).getPortNumber());
portsByName.remove(portName);
}
@@ -362,13 +363,13 @@
if (portsByNumber.get(portNumber) == null) return false;
return portEnabled(portsByNumber.get(portNumber));
}
-
+
@Override
public boolean portEnabled(String portName) {
if (portsByName.get(portName) == null) return false;
return portEnabled(portsByName.get(portName));
}
-
+
@Override
public boolean portEnabled(OFPhysicalPort port) {
if (port == null)
@@ -382,9 +383,9 @@
// return false;
return true;
}
-
+
@Override
- @JsonSerialize(using=DPIDSerializer.class)
+ @JsonSerialize(using = DPIDSerializer.class)
@JsonProperty("dpid")
public long getId() {
if (this.stringId == null)
@@ -424,7 +425,7 @@
@Override
public void sendStatsQuery(OFStatisticsRequest request, int xid,
- IOFMessageListener caller) throws IOException {
+ IOFMessageListener caller) throws IOException {
request.setXid(xid);
this.iofMsgListenersMap.put(xid, caller);
List<OFMessage> msglist = new ArrayList<OFMessage>(1);
@@ -462,7 +463,7 @@
@Override
public void cancelStatisticsReply(int transactionId) {
- if (null == this.statsFutureMap.remove(transactionId)) {
+ if (null == this.statsFutureMap.remove(transactionId)) {
this.iofMsgListenersMap.remove(transactionId);
}
}
@@ -478,8 +479,8 @@
statsFutureMap.clear();
iofMsgListenersMap.clear();
}
-
-
+
+
/**
* @param floodlightProvider the floodlightProvider to set
*/
@@ -487,7 +488,7 @@
public void setFloodlightProvider(IFloodlightProviderService floodlightProvider) {
this.floodlightProvider = floodlightProvider;
}
-
+
@JsonIgnore
public void setThreadPoolService(IThreadPoolService tp) {
this.threadPool = tp;
@@ -504,18 +505,18 @@
public synchronized void setConnected(boolean connected) {
this.connected = connected;
}
-
+
@Override
public Role getRole() {
return role;
}
-
+
@JsonIgnore
@Override
public boolean isActive() {
return (role != Role.SLAVE);
}
-
+
@Override
@JsonIgnore
public void setSwitchProperties(OFDescriptionStatistics description) {
@@ -525,20 +526,20 @@
}
@Override
- @LogMessageDoc(level="ERROR",
- message="Failed to clear all flows on switch {switch}",
- explanation="An I/O error occured while trying to clear " +
- "flows on the switch.",
- recommendation=LogMessageDoc.CHECK_SWITCH)
+ @LogMessageDoc(level = "ERROR",
+ message = "Failed to clear all flows on switch {switch}",
+ explanation = "An I/O error occured while trying to clear " +
+ "flows on the switch.",
+ recommendation = LogMessageDoc.CHECK_SWITCH)
public void clearAllFlowMods() {
// Delete all pre-existing flows
OFMatch match = new OFMatch().setWildcards(OFMatch.OFPFW_ALL);
OFMessage fm = ((OFFlowMod) floodlightProvider.getOFMessageFactory()
- .getMessage(OFType.FLOW_MOD))
+ .getMessage(OFType.FLOW_MOD))
.setMatch(match)
- .setCommand(OFFlowMod.OFPFC_DELETE)
- .setOutPort(OFPort.OFPP_NONE)
- .setLength(U16.t(OFFlowMod.MINIMUM_LENGTH));
+ .setCommand(OFFlowMod.OFPFC_DELETE)
+ .setOutPort(OFPort.OFPP_NONE)
+ .setLength(U16.t(OFFlowMod.MINIMUM_LENGTH));
try {
List<OFMessage> msglist = new ArrayList<OFMessage>(1);
msglist.add(fm);
@@ -564,13 +565,13 @@
@Override
@JsonIgnore
public Map<Short, Long> getPortBroadcastHits() {
- return this.portBroadcastCacheHitMap;
+ return this.portBroadcastCacheHitMap;
}
-
+
@Override
public void flush() {
- Map<OFSwitchImpl,List<OFMessage>> msg_buffer_map = local_msg_buffer.get();
+ Map<OFSwitchImpl, List<OFMessage>> msg_buffer_map = local_msg_buffer.get();
List<OFMessage> msglist = msg_buffer_map.get(this);
if ((msglist != null) && (msglist.size() > 0)) {
try {
@@ -584,7 +585,7 @@
}
public static void flush_all() {
- Map<OFSwitchImpl,List<OFMessage>> msg_buffer_map = local_msg_buffer.get();
+ Map<OFSwitchImpl, List<OFMessage>> msg_buffer_map = local_msg_buffer.get();
for (OFSwitchImpl sw : msg_buffer_map.keySet()) {
sw.flush();
}
@@ -594,7 +595,8 @@
* Return a read lock that must be held while calling the listeners for
* messages from the switch. Holding the read lock prevents the active
* switch list from being modified out from under the listeners.
- * @return
+ *
+ * @return
*/
@JsonIgnore
public Lock getListenerReadLock() {
@@ -606,6 +608,7 @@
* list of active switches. This is to ensure that the active switch list
* doesn't change out from under the listeners as they are handling a
* message from the switch.
+ *
* @return
*/
@JsonIgnore
@@ -615,29 +618,31 @@
/**
* Get the IP Address for the switch
+ *
* @return the inet address
*/
- @JsonSerialize(using=ToStringSerializer.class)
+ @JsonSerialize(using = ToStringSerializer.class)
public SocketAddress getInetAddress() {
return channel.getRemoteAddress();
}
-
+
/**
* Send NX role request message to the switch requesting the specified role.
- *
- * This method should ONLY be called by @see RoleChanger.submitRequest().
- *
+ * <p/>
+ * This method should ONLY be called by @see RoleChanger.submitRequest().
+ * <p/>
* After sending the request add it to the queue of pending request. We
* use the queue to later verify that we indeed receive the correct reply.
- * @param sw switch to send the role request message to
- * @param role role to request
+ *
+ * @param sw switch to send the role request message to
+ * @param role role to request
* @param cookie an opaque value that will be stored in the pending queue so
- * RoleChanger can check for timeouts.
+ * RoleChanger can check for timeouts.
* @return transaction id of the role request message that was sent
*/
protected int sendNxRoleRequest(Role role, long cookie)
throws IOException {
- synchronized(pendingRoleRequests) {
+ synchronized (pendingRoleRequests) {
// Convert the role enum to the appropriate integer constant used
// in the NX role request message
int nxRole = 0;
@@ -653,13 +658,13 @@
break;
default:
log.error("Invalid Role specified for switch {}."
- + " Disconnecting.", this);
+ + " Disconnecting.", this);
// TODO: should throw an error
return 0;
}
-
+
// Construct the role request message
- OFVendor roleRequest = (OFVendor)floodlightProvider.
+ OFVendor roleRequest = (OFVendor) floodlightProvider.
getOFMessageFactory().getMessage(OFType.VENDOR);
int xid = this.getNextTransactionId();
roleRequest.setXid(xid);
@@ -667,79 +672,76 @@
OFRoleRequestVendorData roleRequestData = new OFRoleRequestVendorData();
roleRequestData.setRole(nxRole);
roleRequest.setVendorData(roleRequestData);
- roleRequest.setLengthU(OFVendor.MINIMUM_LENGTH +
- roleRequestData.getLength());
-
+ roleRequest.setLengthU(OFVendor.MINIMUM_LENGTH +
+ roleRequestData.getLength());
+
// Send it to the switch
List<OFMessage> msglist = new ArrayList<OFMessage>(1);
msglist.add(roleRequest);
// FIXME: should this use this.write() in order for messages to
// be processed by handleOutgoingMessage()
this.channel.write(msglist);
-
+
pendingRoleRequests.add(new PendingRoleRequestEntry(xid, role, cookie));
return xid;
}
}
-
- /**
- * Deliver a RoleReply message to this switch. Checks if the reply
- * message matches the expected reply (head of the pending request queue).
+
+ /**
+ * Deliver a RoleReply message to this switch. Checks if the reply
+ * message matches the expected reply (head of the pending request queue).
* We require in-order delivery of replies. If there's any deviation from
- * our expectations we disconnect the switch.
- *
+ * our expectations we disconnect the switch.
+ * <p/>
* We must not check the received role against the controller's current
* role because there's no synchronization but that's fine @see RoleChanger
- *
+ * <p/>
* Will be called by the OFChannelHandler's receive loop
- *
- * @param xid Xid of the reply message
+ *
+ * @param xid Xid of the reply message
* @param role The Role in the the reply message
*/
@LogMessageDocs({
- @LogMessageDoc(level="ERROR",
- message="Switch {switch}: received unexpected role reply for " +
- "Role {role}" +
- " Disconnecting switch",
- explanation="The switch sent an unexpected HA role reply",
- recommendation=HA_CHECK_SWITCH),
- @LogMessageDoc(level="ERROR",
- message="Switch {switch}: expected role reply with " +
- "Xid {xid}, got {xid}. Disconnecting switch",
- explanation="The switch sent an unexpected HA role reply",
- recommendation=HA_CHECK_SWITCH),
- @LogMessageDoc(level="ERROR",
- message="Switch {switch}: expected role reply with " +
- "Role {role}, got {role}. Disconnecting switch",
- explanation="The switch sent an unexpected HA role reply",
- recommendation=HA_CHECK_SWITCH)
+ @LogMessageDoc(level = "ERROR",
+ message = "Switch {switch}: received unexpected role reply for " +
+ "Role {role}" +
+ " Disconnecting switch",
+ explanation = "The switch sent an unexpected HA role reply",
+ recommendation = HA_CHECK_SWITCH),
+ @LogMessageDoc(level = "ERROR",
+ message = "Switch {switch}: expected role reply with " +
+ "Xid {xid}, got {xid}. Disconnecting switch",
+ explanation = "The switch sent an unexpected HA role reply",
+ recommendation = HA_CHECK_SWITCH),
+ @LogMessageDoc(level = "ERROR",
+ message = "Switch {switch}: expected role reply with " +
+ "Role {role}, got {role}. Disconnecting switch",
+ explanation = "The switch sent an unexpected HA role reply",
+ recommendation = HA_CHECK_SWITCH)
})
protected void deliverRoleReply(int xid, Role role) {
- synchronized(pendingRoleRequests) {
+ synchronized (pendingRoleRequests) {
PendingRoleRequestEntry head = pendingRoleRequests.poll();
if (head == null) {
// Maybe don't disconnect if the role reply we received is
// for the same role we are already in.
- log.error("Switch {}: received unexpected role reply for Role {}" +
- " Disconnecting switch", this, role );
+ log.error("Switch {}: received unexpected role reply for Role {}" +
+ " Disconnecting switch", this, role);
this.channel.close();
- }
- else if (head.xid != xid) {
+ } else if (head.xid != xid) {
// check xid before role!!
log.error("Switch {}: expected role reply with " +
- "Xid {}, got {}. Disconnecting switch",
- new Object[] { this, head.xid, xid } );
+ "Xid {}, got {}. Disconnecting switch",
+ new Object[]{this, head.xid, xid});
this.channel.close();
- }
- else if (head.role != role) {
+ } else if (head.role != role) {
log.error("Switch {}: expected role reply with " +
- "Role {}, got {}. Disconnecting switch",
- new Object[] { this, head.role, role } );
+ "Role {}, got {}. Disconnecting switch",
+ new Object[]{this, head.role, role});
this.channel.close();
- }
- else {
+ } else {
log.debug("Received role reply message from {}, setting role to {}",
- this, role);
+ this, role);
if (this.role == null && getAttribute(SWITCH_SUPPORTS_NX_ROLE) == null) {
// The first role reply we received. Set the attribute
// that the switch supports roles
@@ -749,44 +751,47 @@
}
}
}
-
- /**
+
+ /**
* Checks whether the given xid matches the xid of the first pending
- * role request.
+ * role request.
+ *
* @param xid
- * @return
+ * @return
*/
- protected boolean checkFirstPendingRoleRequestXid (int xid) {
- synchronized(pendingRoleRequests) {
+ protected boolean checkFirstPendingRoleRequestXid(int xid) {
+ synchronized (pendingRoleRequests) {
PendingRoleRequestEntry head = pendingRoleRequests.peek();
if (head == null)
return false;
- else
+ else
return head.xid == xid;
}
}
-
+
/**
- * Checks whether the given request cookie matches the cookie of the first
+ * Checks whether the given request cookie matches the cookie of the first
* pending request
+ *
* @param cookie
* @return
*/
protected boolean checkFirstPendingRoleRequestCookie(long cookie) {
- synchronized(pendingRoleRequests) {
+ synchronized (pendingRoleRequests) {
PendingRoleRequestEntry head = pendingRoleRequests.peek();
if (head == null)
return false;
- else
+ else
return head.cookie == cookie;
}
}
-
+
/**
* Called if we receive a vendor error message indicating that roles
* are not supported by the switch. If the xid matches the first pending
* one, we'll mark the switch as not supporting roles and remove the head.
* Otherwise we ignore it.
+ *
* @param xid
*/
protected void deliverRoleRequestNotSupported(int xid) {
@@ -796,21 +801,21 @@
/**
* ONOS Extension to deliverRoleRequestNotSupported().
* This version return the Roll request made.
- * @see deliverRoleRequestNotSupported
+ *
* @param xid
* @return Role of attempted RoleRequest.
+ * @see deliverRoleRequestNotSupported
*/
protected Role deliverRoleRequestNotSupportedEx(int xid) {
- synchronized(pendingRoleRequests) {
+ synchronized (pendingRoleRequests) {
PendingRoleRequestEntry head = pendingRoleRequests.poll();
this.role = null;
- if (head!=null && head.xid == xid) {
+ if (head != null && head.xid == xid) {
setAttribute(SWITCH_SUPPORTS_NX_ROLE, false);
return head.role;
- }
- else {
- log.debug("Closing {} because a role request error didn't match " +
- "head of pendingRoleRequests queue", this);
+ } else {
+ log.debug("Closing {} because a role request error didn't match " +
+ "head of pendingRoleRequests queue", this);
this.channel.close();
return null;
}
@@ -873,9 +878,9 @@
}
- @Override
- public void setupRemoteSwitch(Long dpid) {
- this.datapathId = dpid;
- this.stringId = HexString.toHexString(this.datapathId);
- }
+ @Override
+ public void setupRemoteSwitch(Long dpid) {
+ this.datapathId = dpid;
+ this.stringId = HexString.toHexString(this.datapathId);
+ }
}
diff --git a/src/main/java/net/floodlightcontroller/core/internal/OpenflowPipelineFactory.java b/src/main/java/net/floodlightcontroller/core/internal/OpenflowPipelineFactory.java
index 4485709..e87989d 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/OpenflowPipelineFactory.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/OpenflowPipelineFactory.java
@@ -1,19 +1,19 @@
/**
-* 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.
-**/
+ * 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.internal;
@@ -30,6 +30,7 @@
/**
* Creates a ChannelPipeline for a server-side openflow channel
+ *
* @author readams
*/
public class OpenflowPipelineFactory implements ChannelPipelineFactory {
@@ -39,7 +40,7 @@
protected Timer timer;
protected IdleStateHandler idleHandler;
protected ReadTimeoutHandler readTimeoutHandler;
-
+
public OpenflowPipelineFactory(Controller controller,
ThreadPoolExecutor pipelineExecutor) {
super();
@@ -49,21 +50,21 @@
this.idleHandler = new IdleStateHandler(timer, 20, 25, 0);
this.readTimeoutHandler = new ReadTimeoutHandler(timer, 30);
}
-
+
@Override
public ChannelPipeline getPipeline() throws Exception {
OFChannelState state = new OFChannelState();
-
+
ChannelPipeline pipeline = Channels.pipeline();
pipeline.addLast("ofmessagedecoder", new OFMessageDecoder());
pipeline.addLast("ofmessageencoder", new OFMessageEncoder());
pipeline.addLast("idle", idleHandler);
pipeline.addLast("timeout", readTimeoutHandler);
pipeline.addLast("handshaketimeout",
- new HandshakeTimeoutHandler(state, timer, 60)); // ONOS: was 15 increased it to fix Issue #296
+ new HandshakeTimeoutHandler(state, timer, 60)); // ONOS: was 15 increased it to fix Issue #296
if (pipelineExecutor != null)
pipeline.addLast("pipelineExecutor",
- new ExecutionHandler(pipelineExecutor));
+ new ExecutionHandler(pipelineExecutor));
pipeline.addLast("handler", controller.getChannelHandler(state));
return pipeline;
}
diff --git a/src/main/java/net/floodlightcontroller/core/internal/RoleChanger.java b/src/main/java/net/floodlightcontroller/core/internal/RoleChanger.java
index 4a21cad..6f1a350 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/RoleChanger.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/RoleChanger.java
@@ -15,93 +15,92 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-/**
+/**
* This class handles sending of RoleRequest messages to all connected switches.
- *
+ * <p/>
* Handling Role Requests is tricky. Roles are hard state on the switch and
* we can't query it so we need to make sure that we have consistent states
- * on the switches. Whenever we send a role request to the set of connected
- * switches we need to make sure that we've sent the request to all of them
- * before we process the next change request. If a new switch connects, we
+ * on the switches. Whenever we send a role request to the set of connected
+ * switches we need to make sure that we've sent the request to all of them
+ * before we process the next change request. If a new switch connects, we
* need to send it the current role and need to make sure that the current
* role doesn't change while we are doing it. We achieve this by synchronizing
* all these actions on Controller.roleChanger
- * On the receive side: we need to make sure that we receive a reply for each
- * request we send and that the reply is consistent with the request we sent.
+ * On the receive side: we need to make sure that we receive a reply for each
+ * request we send and that the reply is consistent with the request we sent.
* We'd also like to send the role request to the switch asynchronously in a
* separate thread so we don't block the REST API or other callers.
- *
+ * <p/>
* There are potential ways to relax these synchronization requirements:
* - "Generation ID" for each role request. However, this would be most useful
- * if it were global for the whole cluster
+ * if it were global for the whole cluster
* - Regularly resend the controller's current role. Don't know whether this
- * might have adverse effects on the switch.
- *
+ * might have adverse effects on the switch.
+ * <p/>
* Caveats:
- * - No way to know if another controller (not in our controller cluster)
- * sends MASTER requests to connected switches. Then we would drop to
- * slave role without knowing it. Could regularly resend the current role.
- * Ideally the switch would notify us if it demoted us. What happens if
- * the other controller also regularly resends the same role request?
- * Or if the health check determines that
- * a controller is dead but the controller is still talking to switches (maybe
- * just its health check failed) and resending the master role request....
- * We could try to detect if a switch demoted us to slave even if we think
- * we are master (error messages on packet outs, e.g., when sending LLDPs)
- *
- *
+ * - No way to know if another controller (not in our controller cluster)
+ * sends MASTER requests to connected switches. Then we would drop to
+ * slave role without knowing it. Could regularly resend the current role.
+ * Ideally the switch would notify us if it demoted us. What happens if
+ * the other controller also regularly resends the same role request?
+ * Or if the health check determines that
+ * a controller is dead but the controller is still talking to switches (maybe
+ * just its health check failed) and resending the master role request....
+ * We could try to detect if a switch demoted us to slave even if we think
+ * we are master (error messages on packet outs, e.g., when sending LLDPs)
+ * <p/>
+ * <p/>
* The general model of Role Request handling is as follows:
- *
- * - All role request messages are handled by this class. Class Controller
- * submits a role change request and the request gets queued. submitRequest
- * takes a Collection of switches to which to send the request. We make a copy
- * of this list.
- * - A thread takes these change requests from the queue and sends them to
- * all the switches (using our copy of the switch list).
+ * <p/>
+ * - All role request messages are handled by this class. Class Controller
+ * submits a role change request and the request gets queued. submitRequest
+ * takes a Collection of switches to which to send the request. We make a copy
+ * of this list.
+ * - A thread takes these change requests from the queue and sends them to
+ * all the switches (using our copy of the switch list).
* - The OFSwitchImpl sends the request over the wire and puts the request
- * into a queue of pending request (storing xid and role). We start a timeout
- * to make sure we eventually receive a reply from the switch. We use a single
- * timeout for each request submitted using submitRequest()
+ * into a queue of pending request (storing xid and role). We start a timeout
+ * to make sure we eventually receive a reply from the switch. We use a single
+ * timeout for each request submitted using submitRequest()
* - After the timeout triggers we go over the list of switches again and
- * check that a response has been received (by checking the head of the
- * OFSwitchImpl's queue of pending requests)
+ * check that a response has been received (by checking the head of the
+ * OFSwitchImpl's queue of pending requests)
* - We handle requests and timeouts in the same thread. We use a priority queue
- * to schedule them so we are guaranteed that they are processed in
- * the same order as they are submitted. If a request times out we drop
- * the connection to this switch.
+ * to schedule them so we are guaranteed that they are processed in
+ * the same order as they are submitted. If a request times out we drop
+ * the connection to this switch.
* - Since we decouple submission of role change requests and actually sending
- * them we cannot check a received role reply against the controller's current
- * role because the controller's current role could have changed again.
+ * them we cannot check a received role reply against the controller's current
+ * role because the controller's current role could have changed again.
* - Receiving Role Reply messages is handled by OFChannelHandler and
- * OFSwitchImpl directly. The OFSwitchImpl checks if the received request
- * is as expected (xid and role match the head of the pending queue in
- * OFSwitchImpl). If so
- * the switch updates its role. Otherwise the connection is dropped. If this
- * is the first reply, the SWITCH_SUPPORTS_NX_ROLE attribute is set.
- * Next, we call addSwitch(), removeSwitch() to update the list of active
- * switches if appropriate.
- * - If we receive an Error indicating that roles are not supported by the
- * switch, we set the SWITCH_SUPPORTS_NX_ROLE to false. We keep the
- * switch connection alive while in MASTER and EQUAL role.
- * (TODO: is this the right behavior for EQUAL??). If the role changes to
- * SLAVE the switch connection is dropped (remember: only if the switch
- * doesn't support role requests)
- * The expected behavior is that the switch will probably try to reconnect
- * repeatedly (with some sort of exponential backoff), but after a while
- * will give-up and move on to the next controller-IP configured on the
- * switch. This is the serial failover mechanism from OpenFlow spec v1.0.
- *
+ * OFSwitchImpl directly. The OFSwitchImpl checks if the received request
+ * is as expected (xid and role match the head of the pending queue in
+ * OFSwitchImpl). If so
+ * the switch updates its role. Otherwise the connection is dropped. If this
+ * is the first reply, the SWITCH_SUPPORTS_NX_ROLE attribute is set.
+ * Next, we call addSwitch(), removeSwitch() to update the list of active
+ * switches if appropriate.
+ * - If we receive an Error indicating that roles are not supported by the
+ * switch, we set the SWITCH_SUPPORTS_NX_ROLE to false. We keep the
+ * switch connection alive while in MASTER and EQUAL role.
+ * (TODO: is this the right behavior for EQUAL??). If the role changes to
+ * SLAVE the switch connection is dropped (remember: only if the switch
+ * doesn't support role requests)
+ * The expected behavior is that the switch will probably try to reconnect
+ * repeatedly (with some sort of exponential backoff), but after a while
+ * will give-up and move on to the next controller-IP configured on the
+ * switch. This is the serial failover mechanism from OpenFlow spec v1.0.
+ * <p/>
* New switch connection:
* - Switch handshake is done without sending any role request messages.
* - After handshake completes, switch is added to the list of connected switches
- * and we send the first role request message if role
- * requests are enabled. If roles are disabled automatically promote switch to
- * active switch list and clear FlowTable.
+ * and we send the first role request message if role
+ * requests are enabled. If roles are disabled automatically promote switch to
+ * active switch list and clear FlowTable.
* - When we receive the first reply we proceed as above. In addition, if
- * the role request is for MASTER we wipe the flow table. We do not wipe
- * the flow table if the switch connected while role supported was disabled
- * on the controller.
- *
+ * the role request is for MASTER we wipe the flow table. We do not wipe
+ * the flow table if the switch connected while role supported was disabled
+ * on the controller.
*/
public class RoleChanger {
// FIXME: Upon closer inspection DelayQueue seems to be somewhat broken.
@@ -119,49 +118,58 @@
protected long lastSubmitTime;
protected Thread workerThread;
protected long timeout;
- protected static long DEFAULT_TIMEOUT = 15L*1000*1000*1000L; // 15s
+ protected static long DEFAULT_TIMEOUT = 15L * 1000 * 1000 * 1000L; // 15s
protected final static Logger log = LoggerFactory.getLogger(RoleChanger.class);
- /**
- * A queued task to be handled by the Role changer thread.
+
+ /**
+ * A queued task to be handled by the Role changer thread.
*/
protected static class RoleChangeTask implements Delayed {
- protected enum Type {
- /** This is a request. Dispatch the role update to switches */
+ protected enum Type {
+ /**
+ * This is a request. Dispatch the role update to switches
+ */
REQUEST,
- /** This is a timeout task. Check if all switches have
- correctly replied to the previously dispatched role request */
+ /**
+ * This is a timeout task. Check if all switches have
+ * correctly replied to the previously dispatched role request
+ */
TIMEOUT
}
+
// The set of switches to work on
public Collection<OFSwitchImpl> switches;
public Role role;
public Type type;
// the time when the task should run as nanoTime()
public long deadline;
+
public RoleChangeTask(Collection<OFSwitchImpl> switches, Role role, long deadline) {
this.switches = switches;
this.role = role;
this.type = Type.REQUEST;
this.deadline = deadline;
}
+
@Override
public int compareTo(Delayed o) {
Long timeRemaining = getDelay(TimeUnit.NANOSECONDS);
return timeRemaining.compareTo(o.getDelay(TimeUnit.NANOSECONDS));
}
+
@Override
public long getDelay(TimeUnit tu) {
long timeRemaining = deadline - System.nanoTime();
return tu.convert(timeRemaining, TimeUnit.NANOSECONDS);
}
}
-
- @LogMessageDoc(level="ERROR",
- message="RoleRequestWorker task had an uncaught exception.",
- explanation="An unknown occured while processing an HA " +
- "role change event.",
- recommendation=LogMessageDoc.GENERIC_ACTION)
- protected class RoleRequestWorker extends Thread {
+
+ @LogMessageDoc(level = "ERROR",
+ message = "RoleRequestWorker task had an uncaught exception.",
+ explanation = "An unknown occured while processing an HA " +
+ "role change event.",
+ recommendation = LogMessageDoc.GENERIC_ACTION)
+ protected class RoleRequestWorker extends Thread {
@Override
public void run() {
RoleChangeTask t;
@@ -182,61 +190,59 @@
t.type = RoleChangeTask.Type.TIMEOUT;
t.deadline += timeout;
pendingTasks.put(t);
- }
- else {
+ } else {
verifyRoleReplyReceived(t.switches, t.deadline);
}
}
- }
- catch (Exception e) {
+ } catch (Exception e) {
// Should never get here
- log.error("RoleRequestWorker task had an uncaught exception. ",
- e);
- }
- finally {
+ log.error("RoleRequestWorker task had an uncaught exception. ",
+ e);
+ } finally {
// Be nice in case we earlier caught InterruptedExecution
if (interrupted)
Thread.currentThread().interrupt();
}
} // end loop
}
-
+
public RoleChanger() {
this.pendingTasks = new DelayQueue<RoleChangeTask>();
this.workerThread = new Thread(new RoleRequestWorker());
this.timeout = DEFAULT_TIMEOUT;
this.workerThread.start();
}
-
-
+
+
public synchronized void submitRequest(Collection<OFSwitchImpl> switches, Role role) {
long deadline = System.nanoTime();
// Grrr. stupid DelayQueue. Make sre we have at least 10ms between
// role request messages.
- if (deadline - lastSubmitTime < 10 * 1000*1000)
- deadline = lastSubmitTime + 10 * 1000*1000;
+ if (deadline - lastSubmitTime < 10 * 1000 * 1000)
+ deadline = lastSubmitTime + 10 * 1000 * 1000;
// make a copy of the list
ArrayList<OFSwitchImpl> switches_copy = new ArrayList<OFSwitchImpl>(switches);
RoleChangeTask req = new RoleChangeTask(switches_copy, role, deadline);
pendingTasks.put(req);
lastSubmitTime = deadline;
}
-
+
/**
- * Send a role request message to switches. This checks the capabilities
- * of the switch for understanding role request messaging. Currently we only
- * support the OVS-style role request message, but once the controller
- * supports OF 1.2, this function will also handle sending out the
+ * Send a role request message to switches. This checks the capabilities
+ * of the switch for understanding role request messaging. Currently we only
+ * support the OVS-style role request message, but once the controller
+ * supports OF 1.2, this function will also handle sending out the
* OF 1.2-style role request message.
- * @param switches the collection of switches to send the request too
- * @param role the role to request
+ *
+ * @param switches the collection of switches to send the request too
+ * @param role the role to request
*/
- @LogMessageDoc(level="WARN",
- message="Failed to send role request message " +
+ @LogMessageDoc(level = "WARN",
+ message = "Failed to send role request message " +
"to switch {switch}: {message}. Disconnecting",
- explanation="An I/O error occurred while attempting to change " +
- "the switch HA role.",
- recommendation=LogMessageDoc.CHECK_SWITCH)
+ explanation = "An I/O error occurred while attempting to change " +
+ "the switch HA role.",
+ recommendation = LogMessageDoc.CHECK_SWITCH)
protected void sendRoleRequest(Collection<OFSwitchImpl> switches,
Role role, long cookie) {
// There are three cases to consider:
@@ -268,33 +274,33 @@
// things are configured correctly) it will walk down its list of
// controllers and connect to the current master controller.
Iterator<OFSwitchImpl> iter = switches.iterator();
- while(iter.hasNext()) {
+ while (iter.hasNext()) {
OFSwitchImpl sw = iter.next();
try {
Boolean supportsNxRole = (Boolean)
sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE);
if ((supportsNxRole == null) || supportsNxRole) {
// Handle cases #1 and #2
- log.debug("Sending NxRoleRequest to {}", sw);
+ log.debug("Sending NxRoleRequest to {}", sw);
sw.sendNxRoleRequest(role, cookie);
} else {
- if (role == Role.MASTER) {
- // ONOS extension:
- log.debug("Switch {} doesn't support NxRoleRequests, but sending " +
- "{} request anyway", sw, role);
- //Send the role request anyway, even though we know the switch
- //doesn't support it. The switch will give an error and in our
- //error handling code we will add the switch.
- //NOTE we *could* just add the switch right away rather than
- //going through the overhead of sending a role request - however
- //we then have to deal with concurrency issues resulting from
- //calling addSwitch outside of a netty handler.
- sw.sendNxRoleRequest(role, cookie);
- }
- // Handle case #3
- else if (role == Role.SLAVE) {
+ if (role == Role.MASTER) {
+ // ONOS extension:
+ log.debug("Switch {} doesn't support NxRoleRequests, but sending " +
+ "{} request anyway", sw, role);
+ //Send the role request anyway, even though we know the switch
+ //doesn't support it. The switch will give an error and in our
+ //error handling code we will add the switch.
+ //NOTE we *could* just add the switch right away rather than
+ //going through the overhead of sending a role request - however
+ //we then have to deal with concurrency issues resulting from
+ //calling addSwitch outside of a netty handler.
+ sw.sendNxRoleRequest(role, cookie);
+ }
+ // Handle case #3
+ else if (role == Role.SLAVE) {
log.debug("Disconnecting switch {} that doesn't support " +
- "role request messages from a controller that went to SLAVE mode");
+ "role request messages from a controller that went to SLAVE mode");
// Closing the channel should result in a call to
// channelDisconnect which updates all state
sw.getChannel().close();
@@ -302,33 +308,34 @@
}
}
} catch (IOException e) {
- log.warn("Failed to send role request message " +
- "to switch {}: {}. Disconnecting",
- sw, e);
+ log.warn("Failed to send role request message " +
+ "to switch {}: {}. Disconnecting",
+ sw, e);
sw.getChannel().close();
iter.remove();
}
}
}
-
+
/**
* Verify that switches have received a role reply message we sent earlier
+ *
* @param switches the collection of switches to send the request too
- * @param cookie the cookie of the request
+ * @param cookie the cookie of the request
*/
- @LogMessageDoc(level="WARN",
- message="Timeout while waiting for role reply from switch {switch}."
+ @LogMessageDoc(level = "WARN",
+ message = "Timeout while waiting for role reply from switch {switch}."
+ " Disconnecting",
- explanation="Timed out waiting for the switch to respond to " +
- "a request to change the HA role.",
- recommendation=LogMessageDoc.CHECK_SWITCH)
+ explanation = "Timed out waiting for the switch to respond to " +
+ "a request to change the HA role.",
+ recommendation = LogMessageDoc.CHECK_SWITCH)
protected void verifyRoleReplyReceived(Collection<OFSwitchImpl> switches,
- long cookie) {
- for (OFSwitchImpl sw: switches) {
+ long cookie) {
+ for (OFSwitchImpl sw : switches) {
if (sw.checkFirstPendingRoleRequestCookie(cookie)) {
sw.getChannel().close();
log.warn("Timeout while waiting for role reply from switch {}."
- + " Disconnecting", sw);
+ + " Disconnecting", sw);
}
}
}
diff --git a/src/main/java/net/floodlightcontroller/core/internal/SwitchStateException.java b/src/main/java/net/floodlightcontroller/core/internal/SwitchStateException.java
index d2a928e..8e49799 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/SwitchStateException.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/SwitchStateException.java
@@ -1,24 +1,24 @@
/**
-* 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.
-**/
+ * 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.internal;
/**
- *
+ *
*/
public class SwitchStateException extends Exception {