- SAL/plugin provide service to send Barrier message on demand. FM/application should invoke it explictly for sync purpose.
- LLDP interval is set to 5 mins (configurable thru config.ini: of.discoveryInterval)
- LLDP timeout is set to 1 min (configurable thru config.ini: of.discoveryTimeout). Retry 2 times.
- Switch liveness timeout is set to 60.5 sec (configurable thru config.ini: of.switchLivenessTimeout)
- SAL generates Request ID and passes it down to the plugin (IPluginInFlowProgrammerService: addFlowAsync(Node node, Flow flow, long rid), modifyFlowAsync(), deleteFlowAsync())
- STATS_REPLY timeout is configurable now thru config.ini of.messageResponseTimer
- Same priority messages are in FIFO manner
- Fix invalid ChassisID in LLDP packet
- Debugging messages
- Code style formatting
Signed-off-by: Jason Ye <yisye@cisco.com>
# of.listenPort=6633
# The time (in milliseconds) the controller will wait for a response after sending a Barrier Request or a Statistic Request message (default 2000 msec)
# of.messageResponseTimer=2000
+# The switch liveness timeout value (default 60500 msec)
+# of.switchLivenessTimeout=60500
+# The maximum number of asynchronous messages can be sent before sending a Barrier Request (default 100)
+# of.barrierMessagePriorCount=100
+# The interval which determines how often the discovery packets should be sent (default 300 sec)
+# of.discoveryInterval=300
+# The timeout value in waiting for returned discovery packet (default 60 sec)
+# of.discoveryTimeout=60
# TLS configuration
# To enable TLS, set secureChannelEnabled=true and specify the location of controller Java KeyStore and TrustStore files.
-
/*
* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
/**
* This interface defines an abstraction of an Open Flow Switch.
- *
+ *
*/
public interface ISwitch {
- /**
- * Gets a unique XID.
- * @return XID
- */
- public int getNextXid();
-
- /**
- * Returns the Switch's ID.
- * @return the Switch's ID
- */
- public Long getId();
-
- /**
- * Returns the Switch's table numbers supported by datapath
- * @return the tables
- */
- public Byte getTables();
-
- /**
- * Returns the Switch's bitmap of supported ofp_action_type
- * @return the actions
- */
- public Integer getActions();
-
- /**
- * Returns the Switch's bitmap of supported ofp_capabilities
- * @return the capabilities
- */
- public Integer getCapabilities();
-
- /**
- * Returns the Switch's buffering capacity in Number of Pkts
- * @return the buffers
- */
- public Integer getBuffers();
-
- /**
- * Returns the Date when the switch was connected.
- * @return Date The date when the switch was connected
- */
- public Date getConnectedDate();
-
- /**
- * This method puts the message in an outgoing priority queue with normal
- * priority. It will be served after high priority messages. The method
- * should be used for non-critical messages such as statistics request,
- * discovery packets, etc. An unique XID is generated automatically and
- * inserted into the message.
- *
- * @param msg The OF message to be sent
- * @return The XID used
- */
- public Integer asyncSend(OFMessage msg);
-
- /**
- * This method puts the message in an outgoing priority queue with normal
- * priority. It will be served after high priority messages. The method
- * should be used for non-critical messages such as statistics request,
- * discovery packets, etc. The specified XID is inserted into the message.
- *
- * @param msg The OF message to be Sent
- * @param xid The XID to be used in the message
- * @return The XID used
- */
- public Integer asyncSend(OFMessage msg, int xid);
-
- /**
- * This method puts the message in an outgoing priority queue with high
- * priority. It will be served first before normal priority messages. The
- * method should be used for critical messages such as hello, echo reply
- * etc. An unique XID is generated automatically and inserted into the
- * message.
- *
- * @param msg The OF message to be sent
- * @return The XID used
- */
- public Integer asyncFastSend(OFMessage msg);
-
- /**
- * This method puts the message in an outgoing priority queue with high
- * priority. It will be served first before normal priority messages. The
- * method should be used for critical messages such as hello, echo reply
- * etc. The specified XID is inserted into the message.
- *
- * @param msg The OF message to be sent
- * @return The XID used
- */
- public Integer asyncFastSend(OFMessage msg, int xid);
-
- /**
- * Sends the OF message followed by a Barrier Request with a unique XID which is automatically generated,
- * and waits for a result from the switch.
- * @param msg The message to be sent
- * @return An Object which has one of the followings instances/values:
- * Boolean with value true to indicate the message has been successfully processed and acknowledged by the switch;
- * Boolean with value false to indicate the message has failed to be processed by the switch within a period of time or
- * OFError to indicate that the message has been denied by the switch which responded with OFError.
- */
- public Object syncSend(OFMessage msg);
-
- /**
- * Returns a map containing all OFPhysicalPorts of this switch.
- * @return The Map of OFPhysicalPort
- */
- public Map<Short, OFPhysicalPort> getPhysicalPorts();
-
- /**
- * Returns a Set containing all port IDs of this switch.
- * @return The Set of port ID
- */
- public Set<Short> getPorts();
-
- /**
- * Returns OFPhysicalPort of the specified portNumber of this switch.
- * @param portNumber The port ID
- * @return OFPhysicalPort for the specified PortNumber
- */
- public OFPhysicalPort getPhysicalPort(Short portNumber);
-
- /**
- * Returns the bandwidth of the specified portNumber of this switch.
- * @param portNumber the port ID
- * @return bandwidth
- */
- public Integer getPortBandwidth(Short portNumber);
-
- /**
- * Returns True if the port is enabled,
- * @param portNumber
- * @return True if the port is enabled
- */
- public boolean isPortEnabled(short portNumber);
-
- /**
- * Returns True if the port is enabled.
- * @param port
- * @return True if the port is enabled
- */
- public boolean isPortEnabled(OFPhysicalPort port);
-
- /**
- * Returns a list containing all enabled ports of this switch.
- * @return: List containing all enabled ports of this switch
- */
- public List<OFPhysicalPort> getEnabledPorts();
-
- /**
- * Sends OFStatisticsRequest with a unique XID generated automatically and waits for a result from the switch.
- * @param req the OF Statistic Request to be sent
- * @return Object has one of the following instances/values::
- * List<OFStatistics>, a list of statistics records received from the switch as response from the request;
- * OFError if the switch failed handle the request or
- * NULL if timeout has occurred while waiting for the response.
- */
- public Object getStatistics(OFStatisticsRequest req);
-
- /**
- * Returns true if the switch has reached the operational state (has sent FEATURE_REPLY to the controller).
- * @return true if the switch is operational
- */
- public boolean isOperational();
-
+ /**
+ * Gets a unique XID.
+ *
+ * @return XID
+ */
+ public int getNextXid();
+
+ /**
+ * Returns the Switch's ID.
+ *
+ * @return the Switch's ID
+ */
+ public Long getId();
+
+ /**
+ * Returns the Switch's table numbers supported by datapath
+ *
+ * @return the tables
+ */
+ public Byte getTables();
+
+ /**
+ * Returns the Switch's bitmap of supported ofp_action_type
+ *
+ * @return the actions
+ */
+ public Integer getActions();
+
+ /**
+ * Returns the Switch's bitmap of supported ofp_capabilities
+ *
+ * @return the capabilities
+ */
+ public Integer getCapabilities();
+
+ /**
+ * Returns the Switch's buffering capacity in Number of Pkts
+ *
+ * @return the buffers
+ */
+ public Integer getBuffers();
+
+ /**
+ * Returns the Date when the switch was connected.
+ *
+ * @return Date The date when the switch was connected
+ */
+ public Date getConnectedDate();
+
+ /**
+ * This method puts the message in an outgoing priority queue with normal
+ * priority. It will be served after high priority messages. The method
+ * should be used for non-critical messages such as statistics request,
+ * discovery packets, etc. An unique XID is generated automatically and
+ * inserted into the message.
+ *
+ * @param msg
+ * The OF message to be sent
+ * @return The XID used
+ */
+ public Integer asyncSend(OFMessage msg);
+
+ /**
+ * This method puts the message in an outgoing priority queue with normal
+ * priority. It will be served after high priority messages. The method
+ * should be used for non-critical messages such as statistics request,
+ * discovery packets, etc. The specified XID is inserted into the message.
+ *
+ * @param msg
+ * The OF message to be Sent
+ * @param xid
+ * The XID to be used in the message
+ * @return The XID used
+ */
+ public Integer asyncSend(OFMessage msg, int xid);
+
+ /**
+ * This method puts the message in an outgoing priority queue with high
+ * priority. It will be served first before normal priority messages. The
+ * method should be used for critical messages such as hello, echo reply
+ * etc. An unique XID is generated automatically and inserted into the
+ * message.
+ *
+ * @param msg
+ * The OF message to be sent
+ * @return The XID used
+ */
+ public Integer asyncFastSend(OFMessage msg);
+
+ /**
+ * This method puts the message in an outgoing priority queue with high
+ * priority. It will be served first before normal priority messages. The
+ * method should be used for critical messages such as hello, echo reply
+ * etc. The specified XID is inserted into the message.
+ *
+ * @param msg
+ * The OF message to be sent
+ * @return The XID used
+ */
+ public Integer asyncFastSend(OFMessage msg, int xid);
+
+ /**
+ * Sends the OF message followed by a Barrier Request with a unique XID
+ * which is automatically generated, and waits for a result from the switch.
+ *
+ * @param msg
+ * The message to be sent
+ * @return An Object which has one of the followings instances/values:
+ * Boolean with value true to indicate the message has been
+ * successfully processed and acknowledged by the switch; Boolean
+ * with value false to indicate the message has failed to be
+ * processed by the switch within a period of time or OFError to
+ * indicate that the message has been denied by the switch which
+ * responded with OFError.
+ */
+ public Object syncSend(OFMessage msg);
+
+ /**
+ * Returns a map containing all OFPhysicalPorts of this switch.
+ *
+ * @return The Map of OFPhysicalPort
+ */
+ public Map<Short, OFPhysicalPort> getPhysicalPorts();
+
+ /**
+ * Returns a Set containing all port IDs of this switch.
+ *
+ * @return The Set of port ID
+ */
+ public Set<Short> getPorts();
+
+ /**
+ * Returns OFPhysicalPort of the specified portNumber of this switch.
+ *
+ * @param portNumber
+ * The port ID
+ * @return OFPhysicalPort for the specified PortNumber
+ */
+ public OFPhysicalPort getPhysicalPort(Short portNumber);
+
+ /**
+ * Returns the bandwidth of the specified portNumber of this switch.
+ *
+ * @param portNumber
+ * the port ID
+ * @return bandwidth
+ */
+ public Integer getPortBandwidth(Short portNumber);
+
+ /**
+ * Returns True if the port is enabled,
+ *
+ * @param portNumber
+ * @return True if the port is enabled
+ */
+ public boolean isPortEnabled(short portNumber);
+
+ /**
+ * Returns True if the port is enabled.
+ *
+ * @param port
+ * @return True if the port is enabled
+ */
+ public boolean isPortEnabled(OFPhysicalPort port);
+
+ /**
+ * Returns a list containing all enabled ports of this switch.
+ *
+ * @return: List containing all enabled ports of this switch
+ */
+ public List<OFPhysicalPort> getEnabledPorts();
+
+ /**
+ * Sends OFStatisticsRequest with a unique XID generated automatically and
+ * waits for a result from the switch.
+ *
+ * @param req
+ * the OF Statistic Request to be sent
+ * @return Object has one of the following instances/values::
+ * List<OFStatistics>, a list of statistics records received from
+ * the switch as response from the request; OFError if the switch
+ * failed handle the request or NULL if timeout has occurred while
+ * waiting for the response.
+ */
+ public Object getStatistics(OFStatisticsRequest req);
+
+ /**
+ * Returns true if the switch has reached the operational state (has sent
+ * FEATURE_REPLY to the controller).
+ *
+ * @return true if the switch is operational
+ */
+ public boolean isOperational();
+
+ /**
+ * Sends synchronous Barrier message
+ */
+ public Object sendBarrierMessage();
}
package org.opendaylight.controller.protocol_plugin.openflow.core.internal;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
this.switchStateListener = null;
this.switchInstanceNumber = new AtomicInteger(0);
registerWithOSGIConsole();
-
}
/**
logger.error("Caught exception: " + ex + " during start");
}
}
-
+
/**
* Function called by the dependency manager before the services
* exported by the component are unregistered, this will be
}
public void _controllerShowConnConfig(CommandInterpreter ci) {
- String str = System.getProperty("secureChannelEnabled");
- if ((str != null) && (str.trim().equalsIgnoreCase("true"))) {
- ci.print("The Controller and Switch should communicate through TLS connetion.\n");
-
- String keyStoreFile = System.getProperty("controllerKeyStore");
- String trustStoreFile = System.getProperty("controllerTrustStore");
- if ((keyStoreFile == null) || keyStoreFile.trim().isEmpty()) {
- ci.print("controllerKeyStore not specified in ./configuration/config.ini\n");
- } else {
- ci.print("controllerKeyStore=" + keyStoreFile + "\n");
- }
- if ((trustStoreFile == null) || trustStoreFile.trim().isEmpty()) {
- ci.print("controllerTrustStore not specified in ./configuration/config.ini\n");
- } else {
- ci.print("controllerTrustStore=" + trustStoreFile + "\n");
- }
+ String str = System.getProperty("secureChannelEnabled");
+ if ((str != null) && (str.trim().equalsIgnoreCase("true"))) {
+ ci.print("The Controller and Switch should communicate through TLS connetion.\n");
+
+ String keyStoreFile = System.getProperty("controllerKeyStore");
+ String trustStoreFile = System.getProperty("controllerTrustStore");
+ if ((keyStoreFile == null) || keyStoreFile.trim().isEmpty()) {
+ ci.print("controllerKeyStore not specified in ./configuration/config.ini\n");
+ } else {
+ ci.print("controllerKeyStore=" + keyStoreFile + "\n");
+ }
+ if ((trustStoreFile == null) || trustStoreFile.trim().isEmpty()) {
+ ci.print("controllerTrustStore not specified in ./configuration/config.ini\n");
+ } else {
+ ci.print("controllerTrustStore=" + trustStoreFile + "\n");
+ }
} else {
- ci.print("The Controller and Switch should communicate through TCP connetion.\n");
+ ci.print("The Controller and Switch should communicate through TCP connetion.\n");
}
}
@Override
public String getHelp() {
StringBuffer help = new StringBuffer();
- help.append("--Open Flow Controller --\n");
- help.append("\tcontrollerShowSwitches\n");
- help.append("\tcontrollerReset\n");
- help.append("\tcontrollerShowConnConfig\n");
+ help.append("-- Open Flow Controller --\n");
+ help.append("\t controllerShowSwitches\n");
+ help.append("\t controllerReset\n");
+ help.append("\t controllerShowConnConfig\n");
return help.toString();
}
}
-
/*
* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
private ByteBuffer outBuffer;
private BasicFactory factory;
- public MessageReadWriteService(SocketChannel socket, Selector selector) throws ClosedChannelException {
- this.socket = socket;
- this.selector = selector;
- this.factory = new BasicFactory();
- this.inBuffer = ByteBuffer.allocateDirect(bufferSize);
- this.outBuffer = ByteBuffer.allocateDirect(bufferSize);
- this.clientSelectionKey = this.socket.register(this.selector,
- SelectionKey.OP_READ);
+ public MessageReadWriteService(SocketChannel socket, Selector selector)
+ throws ClosedChannelException {
+ this.socket = socket;
+ this.selector = selector;
+ this.factory = new BasicFactory();
+ this.inBuffer = ByteBuffer.allocateDirect(bufferSize);
+ this.outBuffer = ByteBuffer.allocateDirect(bufferSize);
+ this.clientSelectionKey = this.socket.register(this.selector,
+ SelectionKey.OP_READ);
}
- /**
- * Sends the OF message out over the socket channel.
- *
- * @param msg OF message to be sent
- * @throws Exception
- */
+ /**
+ * Sends the OF message out over the socket channel.
+ *
+ * @param msg
+ * OF message to be sent
+ * @throws Exception
+ */
@Override
public void asyncSend(OFMessage msg) throws IOException {
- synchronized (outBuffer) {
- int msgLen = msg.getLengthU();
- if (outBuffer.remaining() < msgLen) {
- // increase the buffer size so that it can contain this message
- ByteBuffer newBuffer = ByteBuffer.allocateDirect(outBuffer
- .capacity()
- + msgLen);
- outBuffer.flip();
- newBuffer.put(outBuffer);
- outBuffer = newBuffer;
- }
- }
- synchronized (outBuffer) {
- msg.writeTo(outBuffer);
-
- if (!socket.isOpen()) {
- return;
- }
-
- outBuffer.flip();
- socket.write(outBuffer);
- outBuffer.compact();
- if (outBuffer.position() > 0) {
- this.clientSelectionKey = this.socket.register(
- this.selector, SelectionKey.OP_WRITE, this);
- }
- logger.trace("Message sent: {}", msg.toString());
- }
+ synchronized (outBuffer) {
+ int msgLen = msg.getLengthU();
+ if (outBuffer.remaining() < msgLen) {
+ // increase the buffer size so that it can contain this message
+ ByteBuffer newBuffer = ByteBuffer.allocateDirect(outBuffer
+ .capacity() + msgLen);
+ outBuffer.flip();
+ newBuffer.put(outBuffer);
+ outBuffer = newBuffer;
+ }
+ }
+ synchronized (outBuffer) {
+ msg.writeTo(outBuffer);
+
+ if (!socket.isOpen()) {
+ return;
+ }
+
+ outBuffer.flip();
+ socket.write(outBuffer);
+ outBuffer.compact();
+ if (outBuffer.position() > 0) {
+ this.clientSelectionKey = this.socket.register(this.selector,
+ SelectionKey.OP_WRITE, this);
+ }
+ logger.trace("Message sent: {}", msg.toString());
+ }
}
- /**
- * Resumes sending the remaining messages in the outgoing buffer
- * @throws Exception
- */
+ /**
+ * Resumes sending the remaining messages in the outgoing buffer
+ *
+ * @throws Exception
+ */
@Override
public void resumeSend() throws IOException {
- synchronized (outBuffer) {
- if (!socket.isOpen()) {
- return;
- }
-
- outBuffer.flip();
- socket.write(outBuffer);
- outBuffer.compact();
- if (outBuffer.position() > 0) {
- this.clientSelectionKey = this.socket.register(
- this.selector, SelectionKey.OP_WRITE, this);
- } else {
- this.clientSelectionKey = this.socket.register(
- this.selector, SelectionKey.OP_READ, this);
- }
+ synchronized (outBuffer) {
+ if (!socket.isOpen()) {
+ return;
+ }
+
+ outBuffer.flip();
+ socket.write(outBuffer);
+ outBuffer.compact();
+ if (outBuffer.position() > 0) {
+ this.clientSelectionKey = this.socket.register(this.selector,
+ SelectionKey.OP_WRITE, this);
+ } else {
+ this.clientSelectionKey = this.socket.register(this.selector,
+ SelectionKey.OP_READ, this);
+ }
}
}
- /**
- * Reads the incoming network data from the socket and retrieves the OF
- * messages.
- *
- * @return list of OF messages
- * @throws Exception
- */
+ /**
+ * Reads the incoming network data from the socket and retrieves the OF
+ * messages.
+ *
+ * @return list of OF messages
+ * @throws Exception
+ */
@Override
public List<OFMessage> readMessages() throws IOException {
- if (!socket.isOpen()) {
- return null;
- }
+ if (!socket.isOpen()) {
+ return null;
+ }
- List<OFMessage> msgs = null;
- int bytesRead = -1;
+ List<OFMessage> msgs = null;
+ int bytesRead = -1;
bytesRead = socket.read(inBuffer);
if (bytesRead < 0) {
- throw new AsynchronousCloseException();
+ throw new AsynchronousCloseException();
}
inBuffer.flip();
return msgs;
}
- @Override
- public void stop() {
- inBuffer = null;
- outBuffer = null;
- }
+ @Override
+ public void stop() {
+ inBuffer = null;
+ outBuffer = null;
+ }
}
-
/*
* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
package org.opendaylight.controller.protocol_plugin.openflow.core.internal;
+import java.util.concurrent.atomic.AtomicLong;
+
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
* This class describes an OpenFlow message with priority
*/
class PriorityMessage {
- OFMessage msg;
- int priority;
-
- public PriorityMessage(OFMessage msg, int priority) {
- this.msg = msg;
- this.priority = priority;
- }
-
- public OFMessage getMsg() {
- return msg;
- }
-
- public void setMsg(OFMessage msg) {
- this.msg = msg;
- }
-
- public int getPriority() {
- return priority;
- }
-
- public void setPriority(int priority) {
- this.priority = priority;
- }
-
- @Override
+ OFMessage msg;
+ int priority;
+ final static AtomicLong seq = new AtomicLong();
+ final long seqNum;
+
+ public PriorityMessage(OFMessage msg, int priority) {
+ this.msg = msg;
+ this.priority = priority;
+ this.seqNum = seq.getAndIncrement();
+ }
+
+ public OFMessage getMsg() {
+ return msg;
+ }
+
+ public void setMsg(OFMessage msg) {
+ this.msg = msg;
+ }
+
+ public int getPriority() {
+ return priority;
+ }
+
+ public void setPriority(int priority) {
+ this.priority = priority;
+ }
+
+ @Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
@Override
public String toString() {
- return "PriorityMessage[" + ReflectionToStringBuilder.toString(this) + "]";
+ return "PriorityMessage[" + ReflectionToStringBuilder.toString(this)
+ + "]";
}
}
-
/*
* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
private BasicFactory factory;
private SSLEngine sslEngine;
- private SSLEngineResult sslEngineResult; // results from sslEngine last operation
- private ByteBuffer myAppData; // clear text message to be sent
- private ByteBuffer myNetData; // encrypted message to be sent
- private ByteBuffer peerAppData; // clear text message received from the switch
- private ByteBuffer peerNetData; // encrypted message from the switch
+ private SSLEngineResult sslEngineResult; // results from sslEngine last operation
+ private ByteBuffer myAppData; // clear text message to be sent
+ private ByteBuffer myNetData; // encrypted message to be sent
+ private ByteBuffer peerAppData; // clear text message received from the
+ // switch
+ private ByteBuffer peerNetData; // encrypted message from the switch
private FileInputStream kfd = null, tfd = null;
- public SecureMessageReadWriteService(SocketChannel socket, Selector selector) throws Exception {
- this.socket = socket;
- this.selector = selector;
- this.factory = new BasicFactory();
-
- try {
- createSecureChannel(socket);
- createBuffers(sslEngine);
- } catch (Exception e) {
- stop();
- throw e;
- }
+ public SecureMessageReadWriteService(SocketChannel socket, Selector selector)
+ throws Exception {
+ this.socket = socket;
+ this.selector = selector;
+ this.factory = new BasicFactory();
+
+ try {
+ createSecureChannel(socket);
+ createBuffers(sslEngine);
+ } catch (Exception e) {
+ stop();
+ throw e;
+ }
}
- /**
- * Bring up secure channel using SSL Engine
- *
- * @param socket TCP socket channel
- * @throws Exception
- */
+ /**
+ * Bring up secure channel using SSL Engine
+ *
+ * @param socket
+ * TCP socket channel
+ * @throws Exception
+ */
private void createSecureChannel(SocketChannel socket) throws Exception {
- String keyStoreFile = System.getProperty("controllerKeyStore");
- String keyStorePassword = System.getProperty("controllerKeyStorePassword");
- String trustStoreFile = System.getProperty("controllerTrustStore");
- String trustStorePassword = System.getProperty("controllerTrustStorePassword");
-
- if (keyStoreFile != null) {
- keyStoreFile = keyStoreFile.trim();
- }
- if ((keyStoreFile == null) || keyStoreFile.isEmpty()) {
- throw new FileNotFoundException("controllerKeyStore not specified in ./configuration/config.ini");
- }
- if (keyStorePassword != null) {
- keyStorePassword = keyStorePassword.trim();
- }
- if ((keyStorePassword == null) || keyStorePassword.isEmpty()) {
- throw new FileNotFoundException("controllerKeyStorePassword not specified in ./configuration/config.ini");
- }
- if (trustStoreFile != null) {
- trustStoreFile = trustStoreFile.trim();
- }
- if ((trustStoreFile == null) || trustStoreFile.isEmpty()) {
- throw new FileNotFoundException("controllerTrustStore not specified in ./configuration/config.ini");
- }
- if (trustStorePassword != null) {
- trustStorePassword = trustStorePassword.trim();
- }
+ String keyStoreFile = System.getProperty("controllerKeyStore");
+ String keyStorePassword = System
+ .getProperty("controllerKeyStorePassword");
+ String trustStoreFile = System.getProperty("controllerTrustStore");
+ String trustStorePassword = System
+ .getProperty("controllerTrustStorePassword");
+
+ if (keyStoreFile != null) {
+ keyStoreFile = keyStoreFile.trim();
+ }
+ if ((keyStoreFile == null) || keyStoreFile.isEmpty()) {
+ throw new FileNotFoundException(
+ "controllerKeyStore not specified in ./configuration/config.ini");
+ }
+ if (keyStorePassword != null) {
+ keyStorePassword = keyStorePassword.trim();
+ }
+ if ((keyStorePassword == null) || keyStorePassword.isEmpty()) {
+ throw new FileNotFoundException(
+ "controllerKeyStorePassword not specified in ./configuration/config.ini");
+ }
+ if (trustStoreFile != null) {
+ trustStoreFile = trustStoreFile.trim();
+ }
+ if ((trustStoreFile == null) || trustStoreFile.isEmpty()) {
+ throw new FileNotFoundException(
+ "controllerTrustStore not specified in ./configuration/config.ini");
+ }
+ if (trustStorePassword != null) {
+ trustStorePassword = trustStorePassword.trim();
+ }
if ((trustStorePassword == null) || trustStorePassword.isEmpty()) {
- throw new FileNotFoundException("controllerTrustStorePassword not specified in ./configuration/config.ini");
- }
-
+ throw new FileNotFoundException(
+ "controllerTrustStorePassword not specified in ./configuration/config.ini");
+ }
+
KeyStore ks = KeyStore.getInstance("JKS");
KeyStore ts = KeyStore.getInstance("JKS");
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
SecureRandom random = new SecureRandom();
random.nextInt();
- SSLContext sslContext = SSLContext.getInstance("TLS");
+ SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), random);
- sslEngine = sslContext.createSSLEngine();
- sslEngine.setUseClientMode(false);
- sslEngine.setNeedClientAuth(true);
-
- // Do initial handshake
- doHandshake(socket, sslEngine);
-
+ sslEngine = sslContext.createSSLEngine();
+ sslEngine.setUseClientMode(false);
+ sslEngine.setNeedClientAuth(true);
+
+ // Do initial handshake
+ doHandshake(socket, sslEngine);
+
this.clientSelectionKey = this.socket.register(this.selector,
SelectionKey.OP_READ);
}
- /**
- * Sends the OF message out over the socket channel. The message is
- * encrypted by SSL Engine.
- *
- * @param msg OF message to be sent
- * @throws Exception
- */
+ /**
+ * Sends the OF message out over the socket channel. The message is
+ * encrypted by SSL Engine.
+ *
+ * @param msg
+ * OF message to be sent
+ * @throws Exception
+ */
@Override
public void asyncSend(OFMessage msg) throws Exception {
- synchronized (myAppData) {
- int msgLen = msg.getLengthU();
- if (myAppData.remaining() < msgLen) {
- // increase the buffer size so that it can contain this message
- ByteBuffer newBuffer = ByteBuffer.allocateDirect(myAppData
- .capacity()
- + msgLen);
- myAppData.flip();
- newBuffer.put(myAppData);
- myAppData = newBuffer;
- }
- }
- synchronized (myAppData) {
- msg.writeTo(myAppData);
- myAppData.flip();
- sslEngineResult = sslEngine.wrap(myAppData, myNetData);
- logger.trace("asyncSend sslEngine wrap: {}", sslEngineResult);
- runDelegatedTasks(sslEngineResult, sslEngine);
-
- if (!socket.isOpen()) {
- return;
- }
-
- myNetData.flip();
- socket.write(myNetData);
- if (myNetData.hasRemaining()) {
- myNetData.compact();
- } else {
- myNetData.clear();
- }
-
- if (myAppData.hasRemaining()) {
- myAppData.compact();
- this.clientSelectionKey = this.socket.register(
- this.selector, SelectionKey.OP_WRITE, this);
- } else {
- myAppData.clear();
- this.clientSelectionKey = this.socket.register(
- this.selector, SelectionKey.OP_READ, this);
- }
-
- logger.trace("Message sent: {}", msg.toString());
- }
+ synchronized (myAppData) {
+ int msgLen = msg.getLengthU();
+ if (myAppData.remaining() < msgLen) {
+ // increase the buffer size so that it can contain this message
+ ByteBuffer newBuffer = ByteBuffer.allocateDirect(myAppData
+ .capacity() + msgLen);
+ myAppData.flip();
+ newBuffer.put(myAppData);
+ myAppData = newBuffer;
+ }
+ }
+ synchronized (myAppData) {
+ msg.writeTo(myAppData);
+ myAppData.flip();
+ sslEngineResult = sslEngine.wrap(myAppData, myNetData);
+ logger.trace("asyncSend sslEngine wrap: {}", sslEngineResult);
+ runDelegatedTasks(sslEngineResult, sslEngine);
+
+ if (!socket.isOpen()) {
+ return;
+ }
+
+ myNetData.flip();
+ socket.write(myNetData);
+ if (myNetData.hasRemaining()) {
+ myNetData.compact();
+ } else {
+ myNetData.clear();
+ }
+
+ if (myAppData.hasRemaining()) {
+ myAppData.compact();
+ this.clientSelectionKey = this.socket.register(this.selector,
+ SelectionKey.OP_WRITE, this);
+ } else {
+ myAppData.clear();
+ this.clientSelectionKey = this.socket.register(this.selector,
+ SelectionKey.OP_READ, this);
+ }
+
+ logger.trace("Message sent: {}", msg.toString());
+ }
}
- /**
- * Resumes sending the remaining messages in the outgoing buffer
- * @throws Exception
- */
+ /**
+ * Resumes sending the remaining messages in the outgoing buffer
+ *
+ * @throws Exception
+ */
@Override
public void resumeSend() throws Exception {
- synchronized (myAppData) {
- myAppData.flip();
- sslEngineResult = sslEngine.wrap(myAppData, myNetData);
- logger.trace("resumeSend sslEngine wrap: {}", sslEngineResult);
- runDelegatedTasks(sslEngineResult, sslEngine);
-
- if (!socket.isOpen()) {
- return;
- }
-
- myNetData.flip();
- socket.write(myNetData);
- if (myNetData.hasRemaining()) {
- myNetData.compact();
- } else {
- myNetData.clear();
- }
-
- if (myAppData.hasRemaining()) {
- myAppData.compact();
- this.clientSelectionKey = this.socket.register(this.selector,
- SelectionKey.OP_WRITE, this);
- } else {
- myAppData.clear();
- this.clientSelectionKey = this.socket.register(this.selector,
- SelectionKey.OP_READ, this);
- }
- }
+ synchronized (myAppData) {
+ myAppData.flip();
+ sslEngineResult = sslEngine.wrap(myAppData, myNetData);
+ logger.trace("resumeSend sslEngine wrap: {}", sslEngineResult);
+ runDelegatedTasks(sslEngineResult, sslEngine);
+
+ if (!socket.isOpen()) {
+ return;
+ }
+
+ myNetData.flip();
+ socket.write(myNetData);
+ if (myNetData.hasRemaining()) {
+ myNetData.compact();
+ } else {
+ myNetData.clear();
+ }
+
+ if (myAppData.hasRemaining()) {
+ myAppData.compact();
+ this.clientSelectionKey = this.socket.register(this.selector,
+ SelectionKey.OP_WRITE, this);
+ } else {
+ myAppData.clear();
+ this.clientSelectionKey = this.socket.register(this.selector,
+ SelectionKey.OP_READ, this);
+ }
+ }
}
- /**
- * Reads the incoming network data from the socket, decryptes them and then
- * retrieves the OF messages.
- *
- * @return list of OF messages
- * @throws Exception
- */
+ /**
+ * Reads the incoming network data from the socket, decryptes them and then
+ * retrieves the OF messages.
+ *
+ * @return list of OF messages
+ * @throws Exception
+ */
@Override
public List<OFMessage> readMessages() throws Exception {
- if (!socket.isOpen()) {
- return null;
- }
+ if (!socket.isOpen()) {
+ return null;
+ }
- List<OFMessage> msgs = null;
+ List<OFMessage> msgs = null;
int bytesRead = -1;
- int countDown = 50;
-
- bytesRead = socket.read(peerNetData);
- if (bytesRead < 0) {
- logger.debug("Message read operation failed");
- throw new AsynchronousCloseException();
- }
-
- do {
- peerNetData.flip();
- sslEngineResult = sslEngine.unwrap(peerNetData, peerAppData);
- if (peerNetData.hasRemaining()) {
- peerNetData.compact();
- } else {
- peerNetData.clear();
- }
- logger.trace("sslEngine unwrap result: {}", sslEngineResult);
- runDelegatedTasks(sslEngineResult, sslEngine);
- } while ((sslEngineResult.getStatus() == SSLEngineResult.Status.OK) &&
- peerNetData.hasRemaining() && (--countDown > 0));
-
- if (countDown == 0) {
- logger.trace("countDown reaches 0. peerNetData pos {} lim {}", peerNetData.position(), peerNetData.limit());
- }
-
- peerAppData.flip();
- msgs = factory.parseMessages(peerAppData);
- if (peerAppData.hasRemaining()) {
- peerAppData.compact();
- } else {
- peerAppData.clear();
- }
-
- this.clientSelectionKey = this.socket.register(
- this.selector, SelectionKey.OP_READ, this);
-
+ int countDown = 50;
+
+ bytesRead = socket.read(peerNetData);
+ if (bytesRead < 0) {
+ logger.debug("Message read operation failed");
+ throw new AsynchronousCloseException();
+ }
+
+ do {
+ peerNetData.flip();
+ sslEngineResult = sslEngine.unwrap(peerNetData, peerAppData);
+ if (peerNetData.hasRemaining()) {
+ peerNetData.compact();
+ } else {
+ peerNetData.clear();
+ }
+ logger.trace("sslEngine unwrap result: {}", sslEngineResult);
+ runDelegatedTasks(sslEngineResult, sslEngine);
+ } while ((sslEngineResult.getStatus() == SSLEngineResult.Status.OK)
+ && peerNetData.hasRemaining() && (--countDown > 0));
+
+ if (countDown == 0) {
+ logger.trace("countDown reaches 0. peerNetData pos {} lim {}",
+ peerNetData.position(), peerNetData.limit());
+ }
+
+ peerAppData.flip();
+ msgs = factory.parseMessages(peerAppData);
+ if (peerAppData.hasRemaining()) {
+ peerAppData.compact();
+ } else {
+ peerAppData.clear();
+ }
+
+ this.clientSelectionKey = this.socket.register(this.selector,
+ SelectionKey.OP_READ, this);
+
return msgs;
}
/**
- * If the result indicates that we have outstanding tasks to do,
- * go ahead and run them in this thread.
+ * If the result indicates that we have outstanding tasks to do, go ahead
+ * and run them in this thread.
*/
- private void runDelegatedTasks(SSLEngineResult result,
- SSLEngine engine) throws Exception {
-
- if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
- Runnable runnable;
- while ((runnable = engine.getDelegatedTask()) != null) {
- logger.debug("\trunning delegated task...");
- runnable.run();
- }
- HandshakeStatus hsStatus = engine.getHandshakeStatus();
- if (hsStatus == HandshakeStatus.NEED_TASK) {
- throw new Exception(
- "handshake shouldn't need additional tasks");
- }
- logger.debug("\tnew HandshakeStatus: {}", hsStatus);
- }
+ private void runDelegatedTasks(SSLEngineResult result, SSLEngine engine)
+ throws Exception {
+
+ if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
+ Runnable runnable;
+ while ((runnable = engine.getDelegatedTask()) != null) {
+ logger.debug("\trunning delegated task...");
+ runnable.run();
+ }
+ HandshakeStatus hsStatus = engine.getHandshakeStatus();
+ if (hsStatus == HandshakeStatus.NEED_TASK) {
+ throw new Exception("handshake shouldn't need additional tasks");
+ }
+ logger.debug("\tnew HandshakeStatus: {}", hsStatus);
+ }
}
- private void doHandshake(SocketChannel socket, SSLEngine engine) throws Exception {
- SSLSession session = engine.getSession();
- ByteBuffer myAppData = ByteBuffer.allocate(session.getApplicationBufferSize());
- ByteBuffer peerAppData = ByteBuffer.allocate(session.getApplicationBufferSize());
- ByteBuffer myNetData = ByteBuffer.allocate(session.getPacketBufferSize());
- ByteBuffer peerNetData = ByteBuffer.allocate(session.getPacketBufferSize());
-
- // Begin handshake
- engine.beginHandshake();
- SSLEngineResult.HandshakeStatus hs = engine.getHandshakeStatus();
-
- // Process handshaking message
- while (hs != SSLEngineResult.HandshakeStatus.FINISHED &&
- hs != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
- switch (hs) {
- case NEED_UNWRAP:
- // Receive handshaking data from peer
- if (socket.read(peerNetData) < 0) {
- throw new AsynchronousCloseException();
- }
-
- // Process incoming handshaking data
- peerNetData.flip();
- SSLEngineResult res = engine.unwrap(peerNetData, peerAppData);
- peerNetData.compact();
- hs = res.getHandshakeStatus();
-
- // Check status
- switch (res.getStatus()) {
- case OK :
- // Handle OK status
- break;
- }
- break;
-
- case NEED_WRAP :
- // Empty the local network packet buffer.
- myNetData.clear();
-
- // Generate handshaking data
- res = engine.wrap(myAppData, myNetData);
- hs = res.getHandshakeStatus();
-
- // Check status
- switch (res.getStatus()) {
- case OK :
- myNetData.flip();
-
- // Send the handshaking data to peer
- while (myNetData.hasRemaining()) {
- if (socket.write(myNetData) < 0) {
- throw new AsynchronousCloseException();
- }
- }
- break;
- }
- break;
-
- case NEED_TASK :
- // Handle blocking tasks
- Runnable runnable;
- while ((runnable = engine.getDelegatedTask()) != null) {
- logger.debug("\trunning delegated task...");
- runnable.run();
- }
- hs = engine.getHandshakeStatus();
- if (hs == HandshakeStatus.NEED_TASK) {
- throw new Exception(
- "handshake shouldn't need additional tasks");
- }
- logger.debug("\tnew HandshakeStatus: {}", hs);
- break;
- }
- }
+ private void doHandshake(SocketChannel socket, SSLEngine engine)
+ throws Exception {
+ SSLSession session = engine.getSession();
+ ByteBuffer myAppData = ByteBuffer.allocate(session
+ .getApplicationBufferSize());
+ ByteBuffer peerAppData = ByteBuffer.allocate(session
+ .getApplicationBufferSize());
+ ByteBuffer myNetData = ByteBuffer.allocate(session
+ .getPacketBufferSize());
+ ByteBuffer peerNetData = ByteBuffer.allocate(session
+ .getPacketBufferSize());
+
+ // Begin handshake
+ engine.beginHandshake();
+ SSLEngineResult.HandshakeStatus hs = engine.getHandshakeStatus();
+
+ // Process handshaking message
+ while (hs != SSLEngineResult.HandshakeStatus.FINISHED
+ && hs != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
+ switch (hs) {
+ case NEED_UNWRAP:
+ // Receive handshaking data from peer
+ if (socket.read(peerNetData) < 0) {
+ throw new AsynchronousCloseException();
+ }
+
+ // Process incoming handshaking data
+ peerNetData.flip();
+ SSLEngineResult res = engine.unwrap(peerNetData, peerAppData);
+ peerNetData.compact();
+ hs = res.getHandshakeStatus();
+
+ // Check status
+ switch (res.getStatus()) {
+ case OK:
+ // Handle OK status
+ break;
+ }
+ break;
+
+ case NEED_WRAP:
+ // Empty the local network packet buffer.
+ myNetData.clear();
+
+ // Generate handshaking data
+ res = engine.wrap(myAppData, myNetData);
+ hs = res.getHandshakeStatus();
+
+ // Check status
+ switch (res.getStatus()) {
+ case OK:
+ myNetData.flip();
+
+ // Send the handshaking data to peer
+ while (myNetData.hasRemaining()) {
+ if (socket.write(myNetData) < 0) {
+ throw new AsynchronousCloseException();
+ }
+ }
+ break;
+ }
+ break;
+
+ case NEED_TASK:
+ // Handle blocking tasks
+ Runnable runnable;
+ while ((runnable = engine.getDelegatedTask()) != null) {
+ logger.debug("\trunning delegated task...");
+ runnable.run();
+ }
+ hs = engine.getHandshakeStatus();
+ if (hs == HandshakeStatus.NEED_TASK) {
+ throw new Exception(
+ "handshake shouldn't need additional tasks");
+ }
+ logger.debug("\tnew HandshakeStatus: {}", hs);
+ break;
+ }
+ }
}
-
+
private void createBuffers(SSLEngine engine) {
- SSLSession session = engine.getSession();
- this.myAppData = ByteBuffer.allocate(session.getApplicationBufferSize());
- this.peerAppData = ByteBuffer.allocate(session.getApplicationBufferSize());
- this.myNetData = ByteBuffer.allocate(session.getPacketBufferSize());
- this.peerNetData = ByteBuffer.allocate(session.getPacketBufferSize());
+ SSLSession session = engine.getSession();
+ this.myAppData = ByteBuffer
+ .allocate(session.getApplicationBufferSize());
+ this.peerAppData = ByteBuffer.allocate(session
+ .getApplicationBufferSize());
+ this.myNetData = ByteBuffer.allocate(session.getPacketBufferSize());
+ this.peerNetData = ByteBuffer.allocate(session.getPacketBufferSize());
}
- @Override
- public void stop() throws IOException {
- this.sslEngine = null;
- this.sslEngineResult = null;
- this.myAppData = null;
- this.myNetData = null;
- this.peerAppData = null;
- this.peerNetData = null;
-
- if (this.kfd != null) {
- this.kfd.close();
- this.kfd = null;
- }
- if (this.tfd != null) {
- this.tfd.close();
- this.tfd = null;
- }
- }
+ @Override
+ public void stop() throws IOException {
+ this.sslEngine = null;
+ this.sslEngineResult = null;
+ this.myAppData = null;
+ this.myNetData = null;
+ this.peerAppData = null;
+ this.peerNetData = null;
+
+ if (this.kfd != null) {
+ this.kfd.close();
+ this.kfd = null;
+ }
+ if (this.tfd != null) {
+ this.tfd.close();
+ this.tfd = null;
+ }
+ }
}
-
/*
* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
package org.opendaylight.controller.protocol_plugin.openflow.core.internal;
+import java.io.IOException;
import java.net.SocketException;
import java.nio.channels.AsynchronousCloseException;
import java.nio.channels.SelectionKey;
import org.opendaylight.controller.protocol_plugin.openflow.core.ISwitch;
import org.opendaylight.controller.protocol_plugin.openflow.core.IMessageReadWrite;
import org.openflow.protocol.OFBarrierReply;
+import org.openflow.protocol.OFBarrierRequest;
import org.openflow.protocol.OFEchoReply;
import org.openflow.protocol.OFError;
import org.openflow.protocol.OFFeaturesReply;
private static final Logger logger = LoggerFactory
.getLogger(SwitchHandler.class);
private static final int SWITCH_LIVENESS_TIMER = 5000;
- private static final int SWITCH_LIVENESS_TIMEOUT = 2 * SWITCH_LIVENESS_TIMER + 500;
+ private static final int switchLivenessTimeout = getSwitchLivenessTimeout();
private int MESSAGE_RESPONSE_TIMER = 2000;
private String instanceName;
private IMessageReadWrite msgReadWriteService;
private Thread switchHandlerThread;
private Integer responseTimerValue;
- private PriorityBlockingQueue<PriorityMessage> transmitQ;
+ private PriorityBlockingQueue<PriorityMessage> transmitQ;
private Thread transmitThread;
-
+
private enum SwitchState {
NON_OPERATIONAL(0), WAIT_FEATURES_REPLY(1), WAIT_CONFIG_REPLY(2), OPERATIONAL(
3);
this.instanceName = name;
this.thisISwitch = this;
this.sid = (long) 0;
- this.buffers = (int)0;
- this.capabilities = (int)0;
- this.tables = (byte)0;
- this.actions = (int)0;
+ this.buffers = (int) 0;
+ this.capabilities = (int) 0;
+ this.tables = (byte) 0;
+ this.actions = (int) 0;
this.core = core;
this.socket = sc;
this.factory = new BasicFactory();
this.responseTimerValue = MESSAGE_RESPONSE_TIMER;
String rTimer = System.getProperty("of.messageResponseTimer");
if (rTimer != null) {
- try {
- responseTimerValue = Integer.decode(rTimer);
- } catch (NumberFormatException e) {
- logger.warn("Invalid of.messageResponseTimer: {} use default({})",
- rTimer, MESSAGE_RESPONSE_TIMER);
- }
+ try {
+ responseTimerValue = Integer.decode(rTimer);
+ } catch (NumberFormatException e) {
+ logger.warn(
+ "Invalid of.messageResponseTimer: {} use default({})",
+ rTimer, MESSAGE_RESPONSE_TIMER);
+ }
}
- }
+ }
public void start() {
try {
- startTransmitThread();
- setupCommChannel();
- sendFirstHello();
+ startTransmitThread();
+ setupCommChannel();
+ sendFirstHello();
startHandlerThread();
} catch (Exception e) {
reportError(e);
running = true;
while (running) {
try {
- // wait for an incoming connection
+ // wait for an incoming connection
selector.select(0);
Iterator<SelectionKey> selectedKeys = selector
.selectedKeys().iterator();
}
}
} catch (Exception e) {
- reportError(e);
+ reportError(e);
}
}
}
}
public void stop() {
- running = false;
- cancelSwitchTimer();
- try {
- selector.wakeup();
- selector.close();
- } catch (Exception e) {
- }
- try {
- socket.close();
- } catch (Exception e) {
- }
- try {
- msgReadWriteService.stop();
- } catch (Exception e) {
- }
- executor.shutdown();
-
- selector = null;
- socket = null;
- msgReadWriteService = null;
-
- if (switchHandlerThread != null) {
- switchHandlerThread.interrupt();
- }
- if (transmitThread != null) {
- transmitThread.interrupt();
- }
+ running = false;
+ cancelSwitchTimer();
+ try {
+ selector.wakeup();
+ selector.close();
+ } catch (Exception e) {
+ }
+ try {
+ socket.close();
+ } catch (Exception e) {
+ }
+ try {
+ msgReadWriteService.stop();
+ } catch (Exception e) {
+ }
+ executor.shutdown();
+
+ selector = null;
+ msgReadWriteService = null;
+
+ if (switchHandlerThread != null) {
+ switchHandlerThread.interrupt();
+ }
+ if (transmitThread != null) {
+ transmitThread.interrupt();
+ }
}
@Override
return this.xid.incrementAndGet();
}
- /**
- * This method puts the message in an outgoing priority queue with normal
- * priority. It will be served after high priority messages. The method
- * should be used for non-critical messages such as statistics request,
- * discovery packets, etc. An unique XID is generated automatically and
- * inserted into the message.
- *
- * @param msg The OF message to be sent
- * @return The XID used
- */
+ /**
+ * This method puts the message in an outgoing priority queue with normal
+ * priority. It will be served after high priority messages. The method
+ * should be used for non-critical messages such as statistics request,
+ * discovery packets, etc. An unique XID is generated automatically and
+ * inserted into the message.
+ *
+ * @param msg
+ * The OF message to be sent
+ * @return The XID used
+ */
@Override
public Integer asyncSend(OFMessage msg) {
- return asyncSend(msg, getNextXid());
- }
-
- /**
- * This method puts the message in an outgoing priority queue with normal
- * priority. It will be served after high priority messages. The method
- * should be used for non-critical messages such as statistics request,
- * discovery packets, etc. The specified XID is inserted into the message.
- *
- * @param msg The OF message to be Sent
- * @param xid The XID to be used in the message
- * @return The XID used
- */
+ return asyncSend(msg, getNextXid());
+ }
+
+ private Object syncSend(OFMessage msg, int xid) {
+ SynchronousMessage worker = new SynchronousMessage(this, xid, msg);
+ messageWaitingDone.put(xid, worker);
+ Object result = null;
+ Boolean status = false;
+ Future<Object> submit = executor.submit(worker);
+ try {
+ result = submit.get(responseTimerValue, TimeUnit.MILLISECONDS);
+ messageWaitingDone.remove(xid);
+ if (result == null) {
+ // if result is null, then it means the switch can handle this
+ // message successfully
+ // convert the result into a Boolean with value true
+ status = true;
+ // logger.debug("Successfully send " +
+ // msg.getType().toString());
+ result = status;
+ } else {
+ // if result is not null, this means the switch can't handle
+ // this message
+ // the result if OFError already
+ logger.debug("Send {} failed --> {}", msg.getType().toString(),
+ ((OFError) result).toString());
+ }
+ return result;
+ } catch (Exception e) {
+ logger.warn("Timeout while waiting for {} reply", msg.getType()
+ .toString());
+ // convert the result into a Boolean with value false
+ status = false;
+ result = status;
+ return result;
+ }
+ }
+
+ /**
+ * This method puts the message in an outgoing priority queue with normal
+ * priority. It will be served after high priority messages. The method
+ * should be used for non-critical messages such as statistics request,
+ * discovery packets, etc. The specified XID is inserted into the message.
+ *
+ * @param msg
+ * The OF message to be Sent
+ * @param xid
+ * The XID to be used in the message
+ * @return The XID used
+ */
@Override
public Integer asyncSend(OFMessage msg, int xid) {
- msg.setXid(xid);
- if (transmitQ != null) {
- transmitQ.add(new PriorityMessage(msg, 0));
- }
+ msg.setXid(xid);
+ if (transmitQ != null) {
+ transmitQ.add(new PriorityMessage(msg, 0));
+ }
return xid;
}
- /**
- * This method puts the message in an outgoing priority queue with high
- * priority. It will be served first before normal priority messages. The
- * method should be used for critical messages such as hello, echo reply
- * etc. An unique XID is generated automatically and inserted into the
- * message.
- *
- * @param msg The OF message to be sent
- * @return The XID used
- */
+ /**
+ * This method puts the message in an outgoing priority queue with high
+ * priority. It will be served first before normal priority messages. The
+ * method should be used for critical messages such as hello, echo reply
+ * etc. An unique XID is generated automatically and inserted into the
+ * message.
+ *
+ * @param msg
+ * The OF message to be sent
+ * @return The XID used
+ */
@Override
public Integer asyncFastSend(OFMessage msg) {
- return asyncFastSend(msg, getNextXid());
- }
-
- /**
- * This method puts the message in an outgoing priority queue with high
- * priority. It will be served first before normal priority messages. The
- * method should be used for critical messages such as hello, echo reply
- * etc. The specified XID is inserted into the message.
- *
- * @param msg The OF message to be sent
- * @return The XID used
- */
+ return asyncFastSend(msg, getNextXid());
+ }
+
+ /**
+ * This method puts the message in an outgoing priority queue with high
+ * priority. It will be served first before normal priority messages. The
+ * method should be used for critical messages such as hello, echo reply
+ * etc. The specified XID is inserted into the message.
+ *
+ * @param msg
+ * The OF message to be sent
+ * @return The XID used
+ */
@Override
public Integer asyncFastSend(OFMessage msg, int xid) {
- msg.setXid(xid);
- if (transmitQ != null) {
- transmitQ.add(new PriorityMessage(msg, 1));
- }
+ msg.setXid(xid);
+ if (transmitQ != null) {
+ transmitQ.add(new PriorityMessage(msg, 1));
+ }
return xid;
}
- public void resumeSend() {
+ public void resumeSend() {
try {
- if (msgReadWriteService != null) {
- msgReadWriteService.resumeSend();
- }
- } catch (Exception e) {
- reportError(e);
- }
+ if (msgReadWriteService != null) {
+ msgReadWriteService.resumeSend();
+ }
+ } catch (Exception e) {
+ reportError(e);
+ }
}
public void handleMessages() {
List<OFMessage> msgs = null;
-
+
try {
- msgs = msgReadWriteService.readMessages();
- } catch (Exception e) {
- reportError(e);
- }
-
+ msgs = msgReadWriteService.readMessages();
+ } catch (Exception e) {
+ reportError(e);
+ }
+
if (msgs == null) {
logger.debug("{} is down", toString());
// the connection is down, inform core
for (OFMessage msg : msgs) {
logger.trace("Message received: {}", msg.toString());
/*
- if ((msg.getType() != OFType.ECHO_REQUEST) &&
- (msg.getType() != OFType.ECHO_REPLY)) {
- logger.debug(msg.getType().toString() + " received from sw " + toString());
- }
+ * if ((msg.getType() != OFType.ECHO_REQUEST) && (msg.getType() !=
+ * OFType.ECHO_REPLY)) { logger.debug(msg.getType().toString() +
+ * " received from sw " + toString()); }
*/
this.lastMsgReceivedTimeStamp = System.currentTimeMillis();
OFType type = msg.getType();
OFFlowMod flowMod = (OFFlowMod) factory
.getMessage(OFType.FLOW_MOD);
flowMod.setMatch(match).setCommand(OFFlowMod.OFPFC_DELETE)
- .setOutPort(OFPort.OFPP_NONE).setLength(
- (short) OFFlowMod.MINIMUM_LENGTH);
+ .setOutPort(OFPort.OFPP_NONE)
+ .setLength((short) OFFlowMod.MINIMUM_LENGTH);
asyncFastSend(flowMod);
this.state = SwitchState.WAIT_FEATURES_REPLY;
startSwitchTimer();
processFeaturesReply((OFFeaturesReply) msg);
break;
case GET_CONFIG_REPLY:
- // make sure that the switch can send the whole packet to the controller
+ // make sure that the switch can send the whole packet to the
+ // controller
if (((OFGetConfigReply) msg).getMissSendLength() == (short) 0xffff) {
this.state = SwitchState.OPERATIONAL;
}
}
private void processPortStatusMsg(OFPortStatus msg) {
- //short portNumber = msg.getDesc().getPortNumber();
+ // short portNumber = msg.getDesc().getPortNumber();
OFPhysicalPort port = msg.getDesc();
if (msg.getReason() == (byte) OFPortReason.OFPPR_MODIFY.ordinal()) {
updatePhysicalPort(port);
- //logger.debug("Port " + portNumber + " on " + toString() + " modified");
+ // logger.debug("Port " + portNumber + " on " + toString() +
+ // " modified");
} else if (msg.getReason() == (byte) OFPortReason.OFPPR_ADD.ordinal()) {
updatePhysicalPort(port);
- //logger.debug("Port " + portNumber + " on " + toString() + " added");
+ // logger.debug("Port " + portNumber + " on " + toString() +
+ // " added");
} else if (msg.getReason() == (byte) OFPortReason.OFPPR_DELETE
.ordinal()) {
deletePhysicalPort(port);
- //logger.debug("Port " + portNumber + " on " + toString() + " deleted");
+ // logger.debug("Port " + portNumber + " on " + toString() +
+ // " deleted");
}
}
public void run() {
try {
Long now = System.currentTimeMillis();
- if ((now - lastMsgReceivedTimeStamp) > SWITCH_LIVENESS_TIMEOUT) {
+ if ((now - lastMsgReceivedTimeStamp) > switchLivenessTimeout) {
if (probeSent) {
- // switch failed to respond to our probe, consider it down
- logger.warn("{} is idle for too long, disconnect", toString());
+ // switch failed to respond to our probe, consider
+ // it down
+ logger.warn("{} is idle for too long, disconnect",
+ toString());
reportSwitchStateChange(false);
} else {
// send a probe to see if the switch is still alive
- //logger.debug("Send idle probe (Echo Request) to " + switchName());
+ // logger.debug("Send idle probe (Echo Request) to "
+ // + switchName());
probeSent = true;
OFMessage echo = factory
.getMessage(OFType.ECHO_REQUEST);
asyncFastSend(request);
} else {
if (state == SwitchState.WAIT_CONFIG_REPLY) {
- // send another config request
+ // send another config request
OFSetConfig config = (OFSetConfig) factory
.getMessage(OFType.SET_CONFIG);
config.setMissSendLength((short) 0xffff)
}
private void reportError(Exception e) {
- if (e instanceof AsynchronousCloseException ||
- e instanceof InterruptedException ||
- e instanceof SocketException) {
- logger.debug("Caught exception {}", e.getMessage());
- } else {
- logger.warn("Caught exception {}", e.getMessage());
- }
+ if (e instanceof AsynchronousCloseException
+ || e instanceof InterruptedException
+ || e instanceof SocketException
+ || e instanceof IOException) {
+ logger.debug("Caught exception {}", e.getMessage());
+ } else {
+ logger.warn("Caught exception ", e);
+ }
// notify core of this error event and disconnect the switch
((Controller) core).takeSwitchEventError(this);
}
config.setMissSendLength((short) 0xffff).setLengthU(
OFSetConfig.MINIMUM_LENGTH);
asyncFastSend(config);
- // send config request to make sure the switch can handle the set config
+ // send config request to make sure the switch can handle the set
+ // config
OFMessage getConfig = factory.getMessage(OFType.GET_CONFIG_REQUEST);
asyncFastSend(getConfig);
this.state = SwitchState.WAIT_CONFIG_REPLY;
Short portNumber = port.getPortNumber();
physicalPorts.put(portNumber, port);
portBandwidth
- .put(
- portNumber,
+ .put(portNumber,
port.getCurrentFeatures()
& (OFPortFeatures.OFPPF_10MB_FD.getValue()
| OFPortFeatures.OFPPF_10MB_HD
Future<Object> submit = executor.submit(worker);
Object result = null;
try {
- result = submit
- .get(MESSAGE_RESPONSE_TIMER, TimeUnit.MILLISECONDS);
+ result = submit.get(responseTimerValue, TimeUnit.MILLISECONDS);
return result;
} catch (Exception e) {
logger.warn("Timeout while waiting for {} replies", req.getType());
@Override
public Object syncSend(OFMessage msg) {
- Integer xid = getNextXid();
- SynchronousMessage worker = new SynchronousMessage(this, xid, msg);
- messageWaitingDone.put(xid, worker);
- Object result = null;
- Boolean status = false;
- Future<Object> submit = executor.submit(worker);
- try {
- result = submit
- .get(responseTimerValue, TimeUnit.MILLISECONDS);
- messageWaitingDone.remove(xid);
- if (result == null) {
- // if result is null, then it means the switch can handle this message successfully
- // convert the result into a Boolean with value true
- status = true;
- //logger.debug("Successfully send " + msg.getType().toString());
- result = status;
- } else {
- // if result is not null, this means the switch can't handle this message
- // the result if OFError already
- logger.debug("Send {} failed --> {}",
- msg.getType().toString(), ((OFError) result).toString());
- }
- return result;
- } catch (Exception e) {
- logger.warn("Timeout while waiting for {} reply", msg.getType().toString());
- // convert the result into a Boolean with value false
- status = false;
- result = status;
- return result;
- }
+ int xid = getNextXid();
+ return syncSend(msg, xid);
}
/*
- * Either a BarrierReply or a OFError is received. If this is a reply for an outstanding sync message,
- * wake up associated task so that it can continue
+ * Either a BarrierReply or a OFError is received. If this is a reply for an
+ * outstanding sync message, wake up associated task so that it can continue
*/
private void processBarrierReply(OFBarrierReply msg) {
Integer xid = msg.getXid();
xid = errorMsg.getXid();
}
/*
- * the error can be a reply to a synchronous message or to a statistic request message
+ * the error can be a reply to a synchronous message or to a statistic
+ * request message
*/
Callable<?> worker = messageWaitingDone.remove(xid);
if (worker == null) {
worker.wakeup();
}
}
-
+
@Override
public Map<Short, OFPhysicalPort> getPhysicalPorts() {
return this.physicalPorts;
public Byte getTables() {
return this.tables;
}
-
+
@Override
public Integer getActions() {
return this.actions;
}
-
+
@Override
public Integer getCapabilities() {
return this.capabilities;
return result;
}
- /*
- * Transmit thread polls the message out of the priority queue and invokes
- * messaging service to transmit it over the socket channel
- */
+ /*
+ * Transmit thread polls the message out of the priority queue and invokes
+ * messaging service to transmit it over the socket channel
+ */
class PriorityMessageTransmit implements Runnable {
public void run() {
running = true;
while (running) {
- try {
- if (!transmitQ.isEmpty()) {
- PriorityMessage pmsg = transmitQ.poll();
- msgReadWriteService.asyncSend(pmsg.msg);
- logger.trace("Message sent: {}", pmsg.toString());
- }
- Thread.sleep(10);
- } catch (InterruptedException ie) {
- reportError(new InterruptedException("PriorityMessageTransmit thread interrupted"));
- } catch (Exception e) {
- reportError(e);
- }
+ try {
+ if (!transmitQ.isEmpty()) {
+ PriorityMessage pmsg = transmitQ.poll();
+ msgReadWriteService.asyncSend(pmsg.msg);
+ logger.trace("Message sent: {}", pmsg.toString());
+ }
+ Thread.sleep(10);
+ } catch (InterruptedException ie) {
+ reportError(new InterruptedException(
+ "PriorityMessageTransmit thread interrupted"));
+ } catch (Exception e) {
+ reportError(e);
+ }
}
- transmitQ = null;
+ transmitQ = null;
}
}
/*
* Setup and start the transmit thread
*/
- private void startTransmitThread() {
- this.transmitQ = new PriorityBlockingQueue<PriorityMessage>(11,
- new Comparator<PriorityMessage>() {
- public int compare(PriorityMessage p1, PriorityMessage p2) {
- return p2.priority - p1.priority;
- }
- });
+ private void startTransmitThread() {
+ this.transmitQ = new PriorityBlockingQueue<PriorityMessage>(11,
+ new Comparator<PriorityMessage>() {
+ public int compare(PriorityMessage p1, PriorityMessage p2) {
+ if (p2.priority != p1.priority) {
+ return p2.priority - p1.priority;
+ } else {
+ return (p2.seqNum < p1.seqNum) ? 1 : -1;
+ }
+ }
+ });
this.transmitThread = new Thread(new PriorityMessageTransmit());
this.transmitThread.start();
}
-
+
/*
* Setup communication services
*/
private void setupCommChannel() throws Exception {
this.selector = SelectorProvider.provider().openSelector();
this.socket.configureBlocking(false);
- this.socket.socket().setTcpNoDelay(true);
+ this.socket.socket().setTcpNoDelay(true);
this.msgReadWriteService = getMessageReadWriteService();
}
private void sendFirstHello() {
- try {
- OFMessage msg = factory.getMessage(OFType.HELLO);
- asyncFastSend(msg);
- } catch (Exception e) {
- reportError(e);
- }
+ try {
+ OFMessage msg = factory.getMessage(OFType.HELLO);
+ asyncFastSend(msg);
+ } catch (Exception e) {
+ reportError(e);
+ }
}
-
+
private IMessageReadWrite getMessageReadWriteService() throws Exception {
- String str = System.getProperty("secureChannelEnabled");
- return ((str != null) && (str.trim().equalsIgnoreCase("true"))) ?
- new SecureMessageReadWriteService(socket, selector) :
- new MessageReadWriteService(socket, selector);
+ String str = System.getProperty("secureChannelEnabled");
+ return ((str != null) && (str.trim().equalsIgnoreCase("true"))) ? new SecureMessageReadWriteService(
+ socket, selector) : new MessageReadWriteService(socket,
+ selector);
+ }
+
+ /**
+ * Sends synchronous Barrier message
+ */
+ @Override
+ public Object sendBarrierMessage() {
+ OFBarrierRequest barrierMsg = new OFBarrierRequest();
+ return syncSend(barrierMsg);
+ }
+
+ /**
+ * This method returns the switch liveness timeout value. If controller did
+ * not receive any message from the switch for such a long period,
+ * controller will tear down the connection to the switch.
+ *
+ * @return The timeout value
+ */
+ private static int getSwitchLivenessTimeout() {
+ String timeout = System.getProperty("of.switchLivenessTimeout");
+ int rv = 60500;
+
+ try {
+ if (timeout != null) {
+ rv = Integer.parseInt(timeout);
+ }
+ } catch (Exception e) {
+ }
+
+ return rv;
}
}
@Override
public Object call() throws Exception {
sw.asyncSend(syncMsg, xid);
- OFBarrierRequest barrierMsg = new OFBarrierRequest();
- sw.asyncSend(barrierMsg, xid);
+ if (!(syncMsg instanceof OFBarrierRequest)) {
+ OFBarrierRequest barrierMsg = new OFBarrierRequest();
+ sw.asyncSend(barrierMsg, xid);
+ }
latch.await();
return result;
}
new String[] {
IPluginInFlowProgrammerService.class.getName(),
IMessageListener.class.getName(),
- IContainerListener.class.getName() }, props);
+ IContainerListener.class.getName(),
+ IInventoryShimExternalListener.class.getName() },
+ props);
c.add(createServiceDependency()
.setService(IController.class, "(name=Controller)")
private long discoveryTimerTick = 1L * 1000; // per tick in msec
private int discoveryTimerTickCount = 0; // main tick counter
private int discoveryBatchMaxPorts = 500; // max # of ports handled in one batch
- private int discoveryBatchRestartTicks = 30; // periodically restart batching process
- private int discoveryBatchPausePeriod = 2; // pause for few secs
+ private int discoveryBatchRestartTicks = getDiscoveryInterval(); // periodically restart batching process
+ private int discoveryBatchPausePeriod = 5; // pause for few secs
private int discoveryBatchPauseTicks = discoveryBatchRestartTicks - discoveryBatchPausePeriod; // pause after this point
- private int discoveryRetry = 1; // number of retry after initial timeout
- private int discoveryTimeoutTicks = 2; // timeout 2 sec
+ private int discoveryRetry = 2; // number of retry after initial timeout
+ private int discoveryTimeoutTicks = getDiscoveryTimeout(); // timeout in sec
private int discoveryAgeoutTicks = 120; // age out 2 min
private int discoveryConsistencyCheckMultiple = 2; // multiple of discoveryBatchRestartTicks
private int discoveryConsistencyCheckTickCount = discoveryBatchPauseTicks; // CC tick counter
portIdTlv.setType((byte) LLDPTLV.TLVType.PortID.getValue());
// Create LLDP TTL TLV
- byte[] ttl = new byte[] { (byte) 120 };
+ byte[] ttl = new byte[] {(byte) 0, (byte) 120 };
ttlTlv = new LLDPTLV();
ttlTlv.setType((byte) LLDPTLV.TLVType.TTL.getValue()).setLength(
(short) ttl.length).setValue(ttl);
return sourceMac;
}
+
+ /**
+ * This method returns the interval which determines how often the discovery
+ * packets will be sent. Default is 300 seconds.
+ *
+ * @return The discovery interval in second
+ */
+ private static int getDiscoveryInterval() {
+ String elapsedTime = System.getProperty("of.discoveryInterval");
+ int rv = 300;
+
+ try {
+ if (elapsedTime != null) {
+ rv = Integer.parseInt(elapsedTime);
+ }
+ } catch (Exception e) {
+ }
+
+ return rv;
+ }
+
+ /**
+ * This method returns the timeout value in waiting for response of a
+ * discovery query. Default is 60 seconds.
+ *
+ * @return The discovery timeout in second
+ */
+ private static int getDiscoveryTimeout() {
+ String elapsedTime = System.getProperty("of.discoveryTimeout");
+ int rv = 60;
+
+ try {
+ if (elapsedTime != null) {
+ rv = Integer.parseInt(elapsedTime);
+ }
+ } catch (Exception e) {
+ }
+
+ return rv;
+ }
}
import java.nio.ByteBuffer;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import org.eclipse.osgi.framework.console.CommandInterpreter;
+import org.eclipse.osgi.framework.console.CommandProvider;
import org.opendaylight.controller.protocol_plugin.openflow.IFlowProgrammerNotifier;
+import org.opendaylight.controller.protocol_plugin.openflow.IInventoryShimExternalListener;
import org.opendaylight.controller.protocol_plugin.openflow.core.IController;
import org.opendaylight.controller.protocol_plugin.openflow.core.IMessageListener;
import org.opendaylight.controller.protocol_plugin.openflow.core.ISwitch;
import org.opendaylight.controller.sal.core.Node;
import org.opendaylight.controller.sal.core.Node.NodeIDType;
import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.core.Property;
import org.opendaylight.controller.sal.core.UpdateType;
import org.opendaylight.controller.sal.flowprogrammer.Flow;
import org.opendaylight.controller.sal.flowprogrammer.IPluginInFlowProgrammerService;
import org.opendaylight.controller.sal.match.Match;
import org.opendaylight.controller.sal.match.MatchType;
import org.opendaylight.controller.sal.utils.GlobalConstants;
+import org.opendaylight.controller.sal.utils.HexEncode;
import org.opendaylight.controller.sal.utils.NodeCreator;
import org.opendaylight.controller.sal.utils.StatusCode;
import org.opendaylight.controller.sal.utils.Status;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
* the flow programming and relay them to functional modules above SAL.
*/
public class FlowProgrammerService implements IPluginInFlowProgrammerService,
- IMessageListener, IContainerListener {
+ IMessageListener, IContainerListener, IInventoryShimExternalListener,
+ CommandProvider {
private static final Logger log = LoggerFactory
.getLogger(FlowProgrammerService.class);
private IController controller;
private ConcurrentMap<String, IFlowProgrammerNotifier> flowProgrammerNotifiers;
private Map<String, Set<NodeConnector>> containerToNc;
+ private ConcurrentMap<Long, Map<Integer, Long>> xid2rid;
+ private int barrierMessagePriorCount = getBarrierMessagePriorCount();
public FlowProgrammerService() {
controller = null;
flowProgrammerNotifiers = new ConcurrentHashMap<String, IFlowProgrammerNotifier>();
+ xid2rid = new ConcurrentHashMap<Long, Map<Integer, Long>>();
}
public void setController(IController core) {
*/
void init() {
this.controller.addMessageListener(OFType.FLOW_REMOVED, this);
+ registerWithOSGIConsole();
}
/**
@Override
public Status addFlow(Node node, Flow flow) {
+ return addFlowInternal(node, flow, 0);
+ }
+
+ @Override
+ public Status modifyFlow(Node node, Flow oldFlow, Flow newFlow) {
+ return modifyFlowInternal(node, oldFlow, newFlow, 0);
+ }
+
+ @Override
+ public Status removeFlow(Node node, Flow flow) {
+ return removeFlowInternal(node, flow, 0);
+ }
+
+ @Override
+ public Status addFlowAsync(Node node, Flow flow, long rid) {
+ return addFlowInternal(node, flow, rid);
+ }
+
+ @Override
+ public Status modifyFlowAsync(Node node, Flow oldFlow, Flow newFlow,
+ long rid) {
+ return modifyFlowInternal(node, oldFlow, newFlow, rid);
+ }
+
+ @Override
+ public Status removeFlowAsync(Node node, Flow flow, long rid) {
+ return removeFlowInternal(node, flow, rid);
+ }
+
+ private Status addFlowInternal(Node node, Flow flow, long rid) {
String action = "add";
if (!node.getType().equals(NodeIDType.OPENFLOW)) {
return new Status(StatusCode.NOTACCEPTABLE, errorString("send",
FlowConverter x = new FlowConverter(flow);
OFMessage msg = x.getOFFlowMod(OFFlowMod.OFPFC_ADD, null);
- /*
- * Synchronous message send
- */
- Object result = sw.syncSend(msg);
+ Object result;
+ if (rid == 0) {
+ /*
+ * Synchronous message send. Each message is followed by a
+ * Barrier message.
+ */
+ result = sw.syncSend(msg);
+ } else {
+ /*
+ * Message will be sent asynchronously. A Barrier message
+ * will be inserted automatically to synchronize the
+ * progression.
+ */
+ result = asyncMsgSend(node, sw, msg, rid);
+ }
if (result instanceof Boolean) {
return ((Boolean) result == Boolean.TRUE) ? new Status(
StatusCode.SUCCESS, null) : new Status(
"Internal plugin error"));
}
- @Override
- public Status modifyFlow(Node node, Flow oldFlow, Flow newFlow) {
+ private Status modifyFlowInternal(Node node, Flow oldFlow, Flow newFlow, long rid) {
String action = "modify";
if (!node.getType().equals(NodeIDType.OPENFLOW)) {
return new Status(StatusCode.NOTACCEPTABLE, errorString("send",
* Synchronous message send
*/
action = (msg2 == null) ? "modify" : "delete";
- Object result = sw.syncSend(msg1);
+ Object result;
+ if (rid == 0) {
+ /*
+ * Synchronous message send. Each message is followed by a
+ * Barrier message.
+ */
+ result = sw.syncSend(msg1);
+ } else {
+ /*
+ * Message will be sent asynchronously. A Barrier message
+ * will be inserted automatically to synchronize the
+ * progression.
+ */
+ result = asyncMsgSend(node, sw, msg1, rid);
+ }
if (result instanceof Boolean) {
if ((Boolean) result == Boolean.FALSE) {
return new Status(StatusCode.TIMEOUT, errorString(null,
if (msg2 != null) {
action = "add";
- result = sw.syncSend(msg2);
+ if (rid == 0) {
+ /*
+ * Synchronous message send. Each message is followed by a
+ * Barrier message.
+ */
+ result = sw.syncSend(msg2);
+ } else {
+ /*
+ * Message will be sent asynchronously. A Barrier message
+ * will be inserted automatically to synchronize the
+ * progression.
+ */
+ result = asyncMsgSend(node, sw, msg2, rid);
+ }
if (result instanceof Boolean) {
return ((Boolean) result == Boolean.TRUE) ? new Status(
StatusCode.SUCCESS, null) : new Status(
"Internal plugin error"));
}
- @Override
- public Status removeFlow(Node node, Flow flow) {
+ private Status removeFlowInternal(Node node, Flow flow, long rid) {
String action = "remove";
if (!node.getType().equals(NodeIDType.OPENFLOW)) {
return new Status(StatusCode.NOTACCEPTABLE, errorString("send",
if (sw != null) {
OFMessage msg = new FlowConverter(flow).getOFFlowMod(
OFFlowMod.OFPFC_DELETE_STRICT, OFPort.OFPP_NONE);
- Object result = sw.syncSend(msg);
+ Object result;
+ if (rid == 0) {
+ /*
+ * Synchronous message send. Each message is followed by a
+ * Barrier message.
+ */
+ result = sw.syncSend(msg);
+ } else {
+ /*
+ * Message will be sent asynchronously. A Barrier message
+ * will be inserted automatically to synchronize the
+ * progression.
+ */
+ result = asyncMsgSend(node, sw, msg, rid);
+ }
if (result instanceof Boolean) {
return ((Boolean) result == Boolean.TRUE) ? new Status(
StatusCode.SUCCESS, null) : new Status(
break;
default:
}
-
}
@Override
public void containerModeUpdated(UpdateType t) {
}
+
+ @Override
+ public Status sendBarrierMessage(Node node) {
+ if (!node.getType().equals(NodeIDType.OPENFLOW)) {
+ return new Status(StatusCode.NOTACCEPTABLE,
+ "The node does not support Barrier message.");
+ }
+
+ if (controller != null) {
+ long swid = (Long) node.getID();
+ ISwitch sw = controller.getSwitch(swid);
+ if (sw != null) {
+ sw.sendBarrierMessage();
+ clearXid2Rid(swid);
+ return (new Status(StatusCode.SUCCESS, null));
+ } else {
+ return new Status(StatusCode.GONE,
+ "The node does not have a valid Switch reference.");
+ }
+ }
+ return new Status(StatusCode.INTERNALERROR,
+ "Failed to send Barrier message.");
+ }
+
+ /**
+ * This method sends the message asynchronously until the number of messages
+ * sent reaches a threshold. Then a Barrier message is sent automatically
+ * for sync purpose. An unique Request ID associated with the message is
+ * passed down by the caller. The Request ID will be returned to the caller
+ * when an error message is received from the switch.
+ *
+ * @param node
+ * The node
+ * @param msg
+ * The switch
+ * @param msg
+ * The OF message to be sent
+ * @param rid
+ * The Request Id
+ * @return result
+ */
+ private Object asyncMsgSend(Node node, ISwitch sw, OFMessage msg, long rid) {
+ Object result = Boolean.TRUE;
+ long swid = (Long) node.getID();
+ int xid;
+
+ xid = sw.asyncSend(msg);
+ addXid2Rid(swid, xid, rid);
+
+ Map<Integer, Long> swxid2rid = this.xid2rid.get(swid);
+ if (swxid2rid == null) {
+ return result;
+ }
+
+ int size = swxid2rid.size();
+ if (size % barrierMessagePriorCount == 0) {
+ result = sendBarrierMessage(node);
+ }
+
+ return result;
+ }
+
+ /**
+ * A number of async messages are sent followed by a synchronous Barrier
+ * message. This method returns the maximum async messages that can be sent
+ * before the Barrier message.
+ *
+ * @return The max count of async messages sent prior to Barrier message
+ */
+ private int getBarrierMessagePriorCount() {
+ String count = System.getProperty("of.barrierMessagePriorCount");
+ int rv = 100;
+
+ if (count != null) {
+ try {
+ rv = Integer.parseInt(count);
+ } catch (Exception e) {
+ }
+ }
+
+ return rv;
+ }
+
+ /**
+ * This method returns the message Request ID previously assigned by the
+ * caller for a given OF message xid
+ *
+ * @param swid
+ * The switch id
+ * @param xid
+ * The OF message xid
+ * @return The Request ID
+ */
+ public long getMessageRid(long swid, int xid) {
+ Map<Integer, Long> swxid2rid = this.xid2rid.get(swid);
+ long rid = 0;
+
+ if (swxid2rid != null) {
+ rid = swxid2rid.get(xid);
+ }
+ return rid;
+ }
+
+ /**
+ * This method returns a copy of outstanding xid to rid mappings.for a given
+ * switch
+ *
+ * @param swid
+ * The switch id
+ * @return a copy of xid2rid mappings
+ */
+ public Map<Integer, Long> getSwXid2Rid(long swid) {
+ Map<Integer, Long> swxid2rid = this.xid2rid.get(swid);
+
+ if (swxid2rid != null) {
+ return new HashMap<Integer, Long>(swxid2rid);
+ } else {
+ return new HashMap<Integer, Long>();
+ }
+ }
+
+ /**
+ * Adds xid to rid mapping to the local DB
+ *
+ * @param swid
+ * The switch id
+ * @param xid
+ * The OF message xid
+ * @param rid
+ * The message Request ID
+ */
+ private void addXid2Rid(long swid, int xid, long rid) {
+ Map<Integer, Long> swxid2rid = this.xid2rid.get(swid);
+ if (swxid2rid != null) {
+ swxid2rid.put(xid, rid);
+ }
+ }
+
+ /**
+ * When an Error message is received, this method will be invoked to remove
+ * the offending xid from the local DB.
+ *
+ * @param swid
+ * The switch id
+ * @param xid
+ * The OF message xid
+ */
+ private void removeXid2Rid(long swid, int xid) {
+ Map<Integer, Long> swxid2rid = this.xid2rid.get(swid);
+ if (swxid2rid != null) {
+ swxid2rid.remove(xid);
+ }
+ }
+
+ /**
+ * When a Barrier reply is received, this method will be invoked to clear
+ * the local DB
+ *
+ * @param swid
+ * The switch id
+ */
+ private void clearXid2Rid(long swid) {
+ Map<Integer, Long> swxid2rid = this.xid2rid.get(swid);
+ if (swxid2rid != null) {
+ swxid2rid.clear();
+ }
+ }
+
+ @Override
+ public void updateNode(Node node, UpdateType type, Set<Property> props) {
+ long swid = (Long)node.getID();
+
+ switch (type) {
+ case ADDED:
+ Map<Integer, Long> swxid2rid = new HashMap<Integer, Long>();
+ this.xid2rid.put(swid, swxid2rid);
+ break;
+ case CHANGED:
+ break;
+ case REMOVED:
+ this.xid2rid.remove(swid);
+ break;
+ default:
+ }
+ }
+
+ @Override
+ public void updateNodeConnector(NodeConnector nodeConnector,
+ UpdateType type, Set<Property> props) {
+ }
+
+ private void registerWithOSGIConsole() {
+ BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass())
+ .getBundleContext();
+ bundleContext.registerService(CommandProvider.class.getName(), this,
+ null);
+ }
+
+ @Override
+ public String getHelp() {
+ StringBuffer help = new StringBuffer();
+ help.append("-- Flow Programmer Service --\n");
+ help.append("\t px2r <node id> - Print outstanding xid2rid mappings for a given node id\n");
+ help.append("\t px2rc - Print max num of async msgs prior to the Barrier\n");
+ return help.toString();
+ }
+
+ public void _px2r(CommandInterpreter ci) {
+ String st = ci.nextArgument();
+ if (st == null) {
+ ci.println("Please enter a valid node id");
+ return;
+ }
+
+ long sid;
+ try {
+ sid = HexEncode.stringToLong(st);
+ } catch (NumberFormatException e) {
+ ci.println("Please enter a valid node id");
+ return;
+ }
+
+ Map<Integer, Long> swxid2rid = this.xid2rid.get(sid);
+ if (swxid2rid == null) {
+ ci.println("The node id entered does not exist");
+ return;
+ }
+
+ ci.println("xid rid");
+
+ Set<Integer> xidSet = swxid2rid.keySet();
+ if (xidSet == null) {
+ return;
+ }
+
+ for (Integer xid : xidSet) {
+ ci.println(xid + " " + swxid2rid.get(xid));
+ }
+ }
+
+ public void _px2rc(CommandInterpreter ci) {
+ ci.println("Max num of async messages sent prior to the Barrier message is "
+ + barrierMessagePriorCount);
+ }
}
-
/*
* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
* container of the network. Each instance gets container specific inventory
* events from InventoryServiceShim. It interacts with SAL to pass inventory
* data to the upper application.
- *
- *
+ *
+ *
*/
public class InventoryService implements IInventoryShimInternalListener,
IPluginInInventoryService, IStatisticsListener {
private Set<IPluginOutInventoryService> pluginOutInventoryServices = Collections
.synchronizedSet(new HashSet<IPluginOutInventoryService>());
private IController controller = null;
- private ConcurrentMap<Node, Map<String, Property>> nodeProps; // properties are maintained in default container only
- private ConcurrentMap<NodeConnector, Map<String, Property>> nodeConnectorProps; // properties are maintained in default container only
+ private ConcurrentMap<Node, Map<String, Property>> nodeProps; // properties are maintained in global container only
+ private ConcurrentMap<NodeConnector, Map<String, Property>> nodeConnectorProps; // properties are maintained in global container only
private boolean isDefaultContainer = false;
void setController(IController s) {
/**
* Function called by the dependency manager when all the required
* dependencies are satisfied
- *
+ *
*/
@SuppressWarnings("rawtypes")
void init(Component c) {
* Function called by the dependency manager when at least one dependency
* become unsatisfied or when the component is shutting down because for
* example bundle is being stopped.
- *
+ *
*/
void destroy() {
logger.trace("DESTROY called!");
/**
* Function called by dependency manager after "init ()" is called and after
* the services provided by the class are registered in the service registry
- *
+ *
*/
void start() {
logger.trace("START called!");
* Function called by the dependency manager before the services exported by
* the component are unregistered, this will be followed by a "destroy ()"
* calls
- *
+ *
*/
void stop() {
logger.trace("STOP called!");
return null;
Map<Long, ISwitch> switches = controller.getSwitches();
for (Map.Entry<Long, ISwitch> entry : switches.entrySet()) {
- ISwitch sw = entry.getValue();
+ ISwitch sw = entry.getValue();
Node node = OFSwitchToNode(sw);
Map<String, Property> propMap = null;
if (isDefaultContainer) {
byte tables = sw.getTables();
Tables t = new Tables(tables);
if (t != null) {
- propMap.put(Tables.TablesPropName,t);
+ propMap.put(Tables.TablesPropName, t);
}
int cap = sw.getCapabilities();
Capabilities c = new Capabilities(cap);
if (c != null) {
- propMap.put(Capabilities.CapabilitiesPropName, c);
+ propMap.put(Capabilities.CapabilitiesPropName, c);
}
int act = sw.getActions();
Actions a = new Actions(act);
if (a != null) {
- propMap.put(Actions.ActionsPropName,a);
+ propMap.put(Actions.ActionsPropName, a);
}
int buffers = sw.getBuffers();
Buffers b = new Buffers(buffers);
if (b != null) {
- propMap.put(Buffers.BuffersPropName,b);
+ propMap.put(Buffers.BuffersPropName, b);
}
Date connectedSince = sw.getConnectedDate();
Long connectedSinceTime = (connectedSince == null) ? 0
.OFSwitchToProps(sw);
for (Map.Entry<NodeConnector, Set<Property>> entry : ncProps
.entrySet()) {
- updateNodeConnector(entry.getKey(), UpdateType.ADDED, entry
- .getValue());
+ updateNodeConnector(entry.getKey(), UpdateType.ADDED,
+ entry.getValue());
}
}
}
@Override
public void updateNodeConnector(NodeConnector nodeConnector,
UpdateType type, Set<Property> props) {
- logger.trace("NodeConnector id " + nodeConnector.getID()
- + " type " + nodeConnector.getType() + " "
- + type.getName() + " for Node id "
- + nodeConnector.getNode().getID());
-
+ logger.trace("updateNodeConnector {} type {}", nodeConnector,
+ type.getName());
if (nodeConnectorProps == null) {
+ logger.trace("nodeConnectorProps is null");
return;
}
-
- Map<String, Property> propMap = nodeConnectorProps
- .get(nodeConnector);
+ Map<String, Property> propMap = nodeConnectorProps.get(nodeConnector);
switch (type) {
case ADDED:
case CHANGED:
}
}
-
private void updateSwitchProperty(Long switchId, Set<Property> propSet) {
// update local cache
Node node = OFSwitchToNode(controller.getSwitch(switchId));
if (propMap == null) {
propMap = new HashMap<String, Property>();
}
-
+
boolean change = false;
for (Property prop : propSet) {
- String propertyName = prop.getName();
- Property currentProp = propMap.get(propertyName);
- if (!prop.equals(currentProp)) {
- change = true;
- propMap.put(propertyName, prop);
- }
+ String propertyName = prop.getName();
+ Property currentProp = propMap.get(propertyName);
+ if (!prop.equals(currentProp)) {
+ change = true;
+ propMap.put(propertyName, prop);
+ }
}
nodeProps.put(node, propMap);
// Update sal if any of the properties has changed
if (change) {
- synchronized (pluginOutInventoryServices) {
- for (IPluginOutInventoryService service : pluginOutInventoryServices) {
- service.updateNode(node, UpdateType.CHANGED, propSet);
- }
- }
+ synchronized (pluginOutInventoryServices) {
+ for (IPluginOutInventoryService service : pluginOutInventoryServices) {
+ service.updateNode(node, UpdateType.CHANGED, propSet);
+ }
+ }
}
}
}
}
- @Override
- public void descriptionRefreshed(Long switchId,
- OFDescriptionStatistics descriptionStats) {
-
- Set<Property> propSet = new HashSet<Property>(1);
- Description desc =
- new Description(descriptionStats.getDatapathDescription());
- propSet.add(desc);
- this.updateSwitchProperty(switchId, propSet);
- }
+ @Override
+ public void descriptionRefreshed(Long switchId,
+ OFDescriptionStatistics descriptionStats) {
+
+ Set<Property> propSet = new HashSet<Property>(1);
+ Description desc = new Description(
+ descriptionStats.getDatapathDescription());
+ propSet.add(desc);
+ this.updateSwitchProperty(switchId, propSet);
+ }
}
-
/*
* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
* The class describes a shim layer that bridges inventory events from Openflow
* core to various listeners. The notifications are filtered based on container
* configurations.
- *
- *
+ *
+ *
*/
public class InventoryServiceShim implements IContainerListener,
IMessageListener, ISwitchStateListener {
void setInventoryShimInternalListener(Map<?, ?> props,
IInventoryShimInternalListener s) {
if (props == null) {
- logger.error("Didn't receive the service properties");
+ logger.error("setInventoryShimInternalListener property is null");
return;
}
String containerName = (String) props.get("containerName");
if (containerName == null) {
- logger.error("containerName not supplied");
+ logger.error("setInventoryShimInternalListener containerName not supplied");
return;
}
if ((this.inventoryShimInternalListeners != null)
&& !this.inventoryShimInternalListeners.containsValue(s)) {
this.inventoryShimInternalListeners.put(containerName, s);
- logger.trace("Added inventoryShimInternalListener for container:"
- + containerName);
+ logger.trace(
+ "Added inventoryShimInternalListener for container {}",
+ containerName);
}
}
void unsetInventoryShimInternalListener(Map<?, ?> props,
IInventoryShimInternalListener s) {
if (props == null) {
- logger.error("Didn't receive the service properties");
+ logger.error("unsetInventoryShimInternalListener property is null");
return;
}
String containerName = (String) props.get("containerName");
if (containerName == null) {
- logger.error("containerName not supplied");
+ logger.error("unsetInventoryShimInternalListener containerName not supplied");
return;
}
if ((this.inventoryShimInternalListeners != null)
- && this.inventoryShimInternalListeners
- .get(containerName) != null
- && this.inventoryShimInternalListeners
- .get(containerName).equals(s)) {
+ && this.inventoryShimInternalListeners.get(containerName) != null
+ && this.inventoryShimInternalListeners.get(containerName)
+ .equals(s)) {
this.inventoryShimInternalListeners.remove(containerName);
- logger
- .trace("Removed inventoryShimInternalListener for container: "
- + containerName);
+ logger.trace(
+ "Removed inventoryShimInternalListener for container {}",
+ containerName);
}
}
/**
* Function called by the dependency manager when all the required
* dependencies are satisfied
- *
+ *
*/
void init() {
this.controller.addMessageListener(OFType.PORT_STATUS, this);
}
/**
- * Function called after registering the
- * service in OSGi service registry.
+ * Function called after registering the service in OSGi service registry.
*/
void started() {
/* Start with existing switches */
}
/**
- * Function called by the dependency manager when at least one
- * dependency become unsatisfied or when the component is shutting
- * down because for example bundle is being stopped.
- *
+ * Function called by the dependency manager when at least one dependency
+ * become unsatisfied or when the component is shutting down because for
+ * example bundle is being stopped.
+ *
*/
void destroy() {
this.controller.removeMessageListener(OFType.PACKET_IN, this);
type = UpdateType.CHANGED;
}
+ logger.trace("handlePortStatusMessage {} type {}", nodeConnector, type);
+
if (type != null) {
// get node connector properties
Set<Property> props = InventoryServiceHelper.OFPortToProps(m
Map<NodeConnector, Set<Property>> ncProps = InventoryServiceHelper
.OFSwitchToProps(sw);
for (Map.Entry<NodeConnector, Set<Property>> entry : ncProps.entrySet()) {
- notifyInventoryShimListener(entry.getKey(), UpdateType.ADDED, entry
- .getValue());
+ notifyInventoryShimListener(entry.getKey(), UpdateType.ADDED,
+ entry.getValue());
}
// Add this node
if (inventoryShimInternalListener != null) {
inventoryShimInternalListener.updateNodeConnector(nodeConnector,
type, props);
- logger.trace(type + " " + nodeConnector + " on container "
- + container);
+ logger.trace(
+ "notifyInventoryShimInternalListener {} type {} for container {}",
+ nodeConnector, type, container);
}
}
/*
- * Notify all internal and external listeners
+ * Notify all internal and external listeners
*/
private void notifyInventoryShimListener(NodeConnector nodeConnector,
UpdateType type, Set<Property> props) {
- // Always notify default InventoryService. Store properties in default one.
+ // Always notify default InventoryService. Store properties in default
+ // one.
notifyInventoryShimInternalListener(GlobalConstants.DEFAULT.toString(),
nodeConnector, type, props);
}
/*
- * Notify all internal and external listeners
+ * Notify all internal and external listeners
*/
private void notifyInventoryShimListener(Node node, UpdateType type,
Set<Property> props) {
byte tables = sw.getTables();
Tables t = new Tables(tables);
if (t != null) {
- props.add(t);
+ props.add(t);
}
int cap = sw.getCapabilities();
Capabilities c = new Capabilities(cap);
if (c != null) {
- props.add(c);
+ props.add(c);
}
int act = sw.getActions();
Actions a = new Actions(act);
if (a != null) {
- props.add(a);
+ props.add(a);
}
int buffers = sw.getBuffers();
Buffers b = new Buffers(buffers);
if (b != null) {
- props.add(b);
+ props.add(b);
}
// Notify all internal and external listeners
notifyInventoryShimListener(node, type, props);
package org.opendaylight.controller.protocol_plugin.openflow.internal;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
entry = null;
} catch (InterruptedException e1) {
- logger.warn("TopologyNotify interrupted", e1.getMessage());
+ logger.warn("TopologyNotify interrupted {}", e1.getMessage());
if (shuttingDown) {
return;
}
}
} catch (InterruptedException e1) {
logger.warn(
- "Edge Bandwidth Utilization Notify Thread interrupted",
+ "Edge Bandwidth Utilization Notify Thread interrupted {}",
e1.getMessage());
if (shuttingDown) {
return;
&& !this.topologyServiceShimListeners
.containsKey(containerName)) {
this.topologyServiceShimListeners.put(containerName, s);
- logger.trace("Added topologyServiceShimListener for container:"
- + containerName);
+ logger.trace("Added topologyServiceShimListener for container: {}",
+ containerName);
}
}
&& this.topologyServiceShimListeners.get(containerName).equals(
s)) {
this.topologyServiceShimListeners.remove(containerName);
- logger.trace("Removed topologyServiceShimListener for container: "
- + containerName);
+ logger.trace("Removed topologyServiceShimListener for container: {}",
+ containerName);
}
}
}
break;
default:
- logger.debug("Invalid " + type + " Edge " + edge
- + " in container {}", container);
+ logger.debug("notifyEdge: invalid {} for Edge {} in container {}",
+ type, edge, container);
return;
}
notifyQ.add(new NotifyEntry(container, edgeProps, type));
- logger.trace(type + " Edge " + edge + " in container {}", container);
+ logger.debug("notifyEdge: {} Edge {} in container {}",
+ type, edge, container);
}
@Override
-
/*
* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
/**
* Function called by the dependency manager when all the required
* dependencies are satisfied
- *
+ *
*/
@SuppressWarnings("unchecked")
void init(Component c) {
- logger.debug("INIT called!");
+ logger.trace("INIT called!");
Dictionary<Object, Object> props = c.getServiceProperties();
containerName = (props != null) ? (String) props.get("containerName")
: null;
}
/**
- * Function called by the dependency manager when at least one
- * dependency become unsatisfied or when the component is shutting
- * down because for example bundle is being stopped.
- *
+ * Function called by the dependency manager when at least one dependency
+ * become unsatisfied or when the component is shutting down because for
+ * example bundle is being stopped.
+ *
*/
void destroy() {
- logger.debug("DESTROY called!");
+ logger.trace("DESTROY called!");
}
/**
- * Function called by dependency manager after "init ()" is called
- * and after the services provided by the class are registered in
- * the service registry
- *
+ * Function called by dependency manager after "init ()" is called and after
+ * the services provided by the class are registered in the service registry
+ *
*/
void start() {
- logger.debug("START called!");
+ logger.trace("START called!");
}
/**
- * Function called by the dependency manager before the services
- * exported by the component are unregistered, this will be
- * followed by a "destroy ()" calls
- *
+ * Function called by the dependency manager before the services exported by
+ * the component are unregistered, this will be followed by a "destroy ()"
+ * calls
+ *
*/
void stop() {
- logger.debug("STOP called!");
+ logger.trace("STOP called!");
}
/**
* Retrieve SAL service IPluginOutTopologyService
- *
- * @param s Called by Dependency Manager as soon as the SAL
- * service is available
+ *
+ * @param s
+ * Called by Dependency Manager as soon as the SAL service is
+ * available
*/
public void setPluginOutTopologyService(IPluginOutTopologyService s) {
- logger.debug("Setting IPluginOutTopologyService to:" + s);
+ logger.trace("Setting IPluginOutTopologyService to: {}", s);
this.salTopoService = s;
}
/**
* called when SAL service IPluginOutTopologyService is no longer available
- *
- * @param s Called by Dependency Manager as soon as the SAL
- * service is unavailable
+ *
+ * @param s
+ * Called by Dependency Manager as soon as the SAL service is
+ * unavailable
*/
public void unsetPluginOutTopologyService(IPluginOutTopologyService s) {
if (this.salTopoService == s) {
- logger.debug("UNSetting IPluginOutTopologyService from:" + s);
+ logger.trace("UNSetting IPluginOutTopologyService from: {}", s);
this.salTopoService = null;
}
}
/**
* Retrieve OF protocol_plugin service IRefreshInternalProvider
- *
- * @param s Called by Dependency Manager as soon as the SAL
- * service is available
+ *
+ * @param s
+ * Called by Dependency Manager as soon as the SAL service is
+ * available
*/
public void setRefreshInternalProvider(IRefreshInternalProvider s) {
- logger.debug("Setting IRefreshInternalProvider to:" + s);
+ logger.trace("Setting IRefreshInternalProvider to: {}", s);
this.topoRefreshService = s;
}
/**
- * called when OF protocol_plugin service IRefreshInternalProvider
- * is no longer available
- *
- * @param s Called by Dependency Manager as soon as the SAL
- * service is unavailable
+ * called when OF protocol_plugin service IRefreshInternalProvider is no
+ * longer available
+ *
+ * @param s
+ * Called by Dependency Manager as soon as the SAL service is
+ * unavailable
*/
public void unsetRefreshInternalProvider(IRefreshInternalProvider s) {
if (this.topoRefreshService == s) {
- logger.debug("UNSetting IRefreshInternalProvider from:" + s);
+ logger.trace("UNSetting IRefreshInternalProvider from: {}", s);
this.topoRefreshService = null;
}
}
*/
public interface IFlowProgrammerService {
/**
- * Add a flow to the network node
+ * Synchronously add a flow to the network node
*
* @param node
* @param flow
Status addFlow(Node node, Flow flow);
/**
- * Modify existing flow on the switch
+ * Synchronously modify existing flow on the switch
*
* @param node
* @param flow
*/
- Status modifyFlow(Node node, Flow oldflow, Flow newFlow);
+ Status modifyFlow(Node node, Flow oldFlow, Flow newFlow);
/**
- * Remove the flow from the network node
+ * Synchronously remove the flow from the network node
*
* @param node
* @param flow
*/
Status removeFlow(Node node, Flow flow);
+ /**
+ * Asynchronously add a flow to the network node
+ *
+ * @param node
+ * @param flow
+ */
+ Status addFlowAsync(Node node, Flow flow);
+
+ /**
+ * Asynchronously modify existing flow on the switch
+ *
+ * @param node
+ * @param flow
+ */
+ Status modifyFlowAsync(Node node, Flow oldFlow, Flow newFlow);
+
+ /**
+ * Asynchronously remove the flow from the network node
+ *
+ * @param node
+ * @param flow
+ */
+ Status removeFlowAsync(Node node, Flow flow);
+
/**
* Remove all flows present on the network node
*
* @param node
*/
Status removeAllFlows(Node node);
+
+ /**
+ * Send synchronous Barrier message
+ *
+ * @param node
+ */
+ Status sendBarrierMessage(Node node);
}
*/
public interface IPluginInFlowProgrammerService {
/**
- * Add a flow to the network node
+ * Synchronously add a flow to the network node
*
* @param node
* @param flow
Status addFlow(Node node, Flow flow);
/**
- * Modify existing flow on the switch
+ * Synchronously modify existing flow on the switch
*
* @param node
* @param flow
Status modifyFlow(Node node, Flow oldFlow, Flow newFlow);
/**
- * Remove the flow from the network node
+ * Synchronously remove the flow from the network node
*
* @param node
* @param flow
*/
Status removeFlow(Node node, Flow flow);
+ /**
+ * Asynchronously add a flow to the network node
+ *
+ * @param node
+ * @param flow
+ * @param rid
+ */
+ Status addFlowAsync(Node node, Flow flow, long rid);
+
+ /**
+ * Asynchronously modify existing flow on the switch
+ *
+ * @param node
+ * @param flow
+ * @param rid
+ */
+ Status modifyFlowAsync(Node node, Flow oldFlow, Flow newFlow, long rid);
+
+ /**
+ * Asynchronously remove the flow from the network node
+ *
+ * @param node
+ * @param flow
+ * @param rid
+ */
+ Status removeFlowAsync(Node node, Flow flow, long rid);
+
/**
* Remove all flows present on the network node
*
* @param node
*/
Status removeAllFlows(Node node);
+
+ /**
+ * Send synchronous Barrier message
+ *
+ * @param node
+ */
+ Status sendBarrierMessage(Node node);
}
-
/*
* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
private static final String LENGTH = "Length";
private static final String VALUE = "Value";
private static final int LLDPTLVFields = 3;
- public static final byte[] OFOUI = new byte[] {(byte)0x00, (byte)0x26, (byte)0xe1}; // OpenFlow OUI
- public static final byte[] customTlvSubType = new byte[] {0};
- public static final int customTlvOffset = OFOUI.length + customTlvSubType.length;
- public static final byte chassisIDSubType[] = new byte[] {4}; // MAC address for the system
- public static final byte portIDSubType[] = new byte[] {7}; // locally assigned
-
- public enum TLVType {
- Unknown ((byte)0),
- ChassisID ((byte)1),
- PortID ((byte)2),
- TTL ((byte)3),
- PortDesc ((byte)4),
- SystemName ((byte)5),
- SystemDesc ((byte)6),
- Custom ((byte)127);
-
- private byte value;
- private TLVType(byte value) {
- this.value = value;
- }
- public byte getValue() {
- return value;
- }
- }
+ public static final byte[] OFOUI = new byte[] { (byte) 0x00, (byte) 0x26,
+ (byte) 0xe1 }; // OpenFlow OUI
+ public static final byte[] customTlvSubType = new byte[] { 0 };
+ public static final int customTlvOffset = OFOUI.length
+ + customTlvSubType.length;
+ public static final byte chassisIDSubType[] = new byte[] { 4 }; // MAC address for the system
+ public static final byte portIDSubType[] = new byte[] { 7 }; // locally assigned
+
+ public enum TLVType {
+ Unknown((byte) 0), ChassisID((byte) 1), PortID((byte) 2), TTL((byte) 3), PortDesc(
+ (byte) 4), SystemName((byte) 5), SystemDesc((byte) 6), Custom(
+ (byte) 127);
+
+ private byte value;
+
+ private TLVType(byte value) {
+ this.value = value;
+ }
+
+ public byte getValue() {
+ return value;
+ }
+ }
private static Map<String, Pair<Integer, Integer>> fieldCoordinates = new LinkedHashMap<String, Pair<Integer, Integer>>() {
private static final long serialVersionUID = 1L;
protected Map<String, byte[]> fieldValues;
/**
- * Default constructor that creates and sets the hash map values
- * and sets the payload to null
+ * Default constructor that creates and sets the hash map values and sets
+ * the payload to null
*/
public LLDPTLV() {
payload = null;
}
/**
- * Constructor that writes the passed LLDPTLV values to the
- * hdrFieldsMap
+ * Constructor that writes the passed LLDPTLV values to the hdrFieldsMap
*/
public LLDPTLV(LLDPTLV other) {
for (Map.Entry<String, byte[]> entry : other.hdrFieldsMap.entrySet()) {
/**
* Returns the size in bits of the whole TLV
+ *
* @return int - size in bits of full TLV
* @throws Exception
*/
LLDPTLV.fieldCoordinates.get(LENGTH).getRight() + // static
getfieldnumBits(VALUE)); // variable
}
-
+
/**
- * Creates the ChassisID TLV value including the subtype and ChassisID string
+ * Creates the ChassisID TLV value including the subtype and ChassisID
+ * string
*
- * @param nodeId node identifier string
+ * @param nodeId
+ * node identifier string
* @return the ChassisID TLV value in byte array
*/
static public byte[] createChassisIDTLVValue(String nodeId) {
- byte[] cid = HexEncode.bytesFromHexString(nodeId);
+ byte[] nid = HexEncode.bytesFromHexString(nodeId);
+ byte[] cid = new byte[6];
+ int srcPos = 0, dstPos = 0;
+
+ if (nid.length > cid.length) {
+ srcPos = nid.length - cid.length;
+ } else {
+ dstPos = cid.length - nid.length;
+ }
+ System.arraycopy(nid, srcPos, cid, dstPos, cid.length);
+
byte[] cidValue = new byte[cid.length + chassisIDSubType.length];
- System.arraycopy(chassisIDSubType, 0, cidValue, 0, chassisIDSubType.length);
+ System.arraycopy(chassisIDSubType, 0, cidValue, 0,
+ chassisIDSubType.length);
System.arraycopy(cid, 0, cidValue, chassisIDSubType.length, cid.length);
- return cidValue;
+ return cidValue;
}
/**
* Creates the PortID TLV value including the subtype and PortID string
*
- * @param portId port identifier string
+ * @param portId
+ * port identifier string
* @return the PortID TLV value in byte array
*/
static public byte[] createPortIDTLVValue(String portId) {
System.arraycopy(portIDSubType, 0, pidValue, 0, portIDSubType.length);
System.arraycopy(pid, 0, pidValue, portIDSubType.length, pid.length);
- return pidValue;
+ return pidValue;
}
/**
* Creates the custom TLV value including OUI, subtype and custom string
*
- * @param portId port identifier string
+ * @param portId
+ * port identifier string
* @return the custom TLV value in byte array
*/
static public byte[] createCustomTLVValue(String customString) {
System.arraycopy(customArray, 0, customValue, customTlvOffset,
customArray.length);
- return customValue;
+ return customValue;
}
/**
* Retrieves the string from TLV value and returns it in HexString format
*
- * @param tlvValue the TLV value
- * @param tlvLen the TLV length
+ * @param tlvValue
+ * the TLV value
+ * @param tlvLen
+ * the TLV length
* @return the HexString
*/
static public String getHexStringValue(byte[] tlvValue, int tlvLen) {
- byte[] cidBytes = new byte[tlvLen - chassisIDSubType.length];
- System.arraycopy(tlvValue, chassisIDSubType.length, cidBytes, 0, cidBytes.length);
- return HexEncode.bytesToHexStringFormat(cidBytes);
+ byte[] cidBytes = new byte[tlvLen - chassisIDSubType.length];
+ System.arraycopy(tlvValue, chassisIDSubType.length, cidBytes, 0,
+ cidBytes.length);
+ return HexEncode.bytesToHexStringFormat(cidBytes);
}
/**
* Retrieves the string from TLV value
*
- * @param tlvValue the TLV value
- * @param tlvLen the TLV length
+ * @param tlvValue
+ * the TLV value
+ * @param tlvLen
+ * the TLV length
* @return the string
*/
static public String getStringValue(byte[] tlvValue, int tlvLen) {
- byte[] pidBytes = new byte[tlvLen - portIDSubType.length];
- System.arraycopy(tlvValue, portIDSubType.length, pidBytes, 0, pidBytes.length);
- return (new String(pidBytes));
+ byte[] pidBytes = new byte[tlvLen - portIDSubType.length];
+ System.arraycopy(tlvValue, portIDSubType.length, pidBytes, 0,
+ pidBytes.length);
+ return (new String(pidBytes));
}
/**
- * Retrieves the custom string from the Custom TLV value which includes OUI, subtype and custom string
+ * Retrieves the custom string from the Custom TLV value which includes OUI,
+ * subtype and custom string
*
- * @param customTlvValue the custom TLV value
- * @param customTlvLen the custom TLV length
+ * @param customTlvValue
+ * the custom TLV value
+ * @param customTlvLen
+ * the custom TLV length
* @return the custom string
*/
static public String getCustomString(byte[] customTlvValue, int customTlvLen) {
if (Arrays.equals(vendor, LLDPTLV.OFOUI)) {
int customArrayLength = customTlvLen - customTlvOffset;
byte[] customArray = new byte[customArrayLength];
- System.arraycopy(customTlvValue, customTlvOffset,
- customArray, 0, customArrayLength);
+ System.arraycopy(customTlvValue, customTlvOffset, customArray, 0,
+ customArrayLength);
try {
- customString = new String(customArray, "UTF-8");
+ customString = new String(customArray, "UTF-8");
} catch (UnsupportedEncodingException e) {
}
}
-
- return customString;
- }
+
+ return customString;
+ }
}
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicLong;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
.getLogger(FlowProgrammerService.class);
private ConcurrentHashMap<String, IPluginInFlowProgrammerService> pluginFlowProgrammer;
private Set<IFlowProgrammerListener> listener;
+ private AtomicLong seq;
public FlowProgrammerService() {
pluginFlowProgrammer = new ConcurrentHashMap<String, IPluginInFlowProgrammerService>();
listener = new HashSet<IFlowProgrammerListener>();
+ seq = new AtomicLong();
+ /*
+ * This Request ID generator starts with 1. Each aysnc message is
+ * associated with an unique Request ID (!= 0).
+ */
+ seq.lazySet(1);
}
/**
return new Status(StatusCode.NOSERVICE, "Plugin unuvailable");
}
+ @Override
+ public Status addFlowAsync(Node node, Flow flow) {
+ if (pluginFlowProgrammer != null) {
+ if (this.pluginFlowProgrammer.get(node.getType()) != null) {
+ return this.pluginFlowProgrammer.get(node.getType()).addFlowAsync(
+ node, flow, getNextRid());
+ }
+ }
+ return new Status(StatusCode.NOSERVICE, "Plugin unuvailable");
+ }
+
+ @Override
+ public Status removeFlowAsync(Node node, Flow flow) {
+ if (pluginFlowProgrammer != null) {
+ if (this.pluginFlowProgrammer.get(node.getType()) != null) {
+ return this.pluginFlowProgrammer.get(node.getType())
+ .removeFlowAsync(node, flow, getNextRid());
+ }
+ }
+ return new Status(StatusCode.NOSERVICE, "Plugin unuvailable");
+ }
+
+ @Override
+ public Status modifyFlowAsync(Node node, Flow oldFlow, Flow newFlow) {
+ if (pluginFlowProgrammer != null) {
+ if (this.pluginFlowProgrammer.get(node.getType()) != null) {
+ return this.pluginFlowProgrammer.get(node.getType())
+ .modifyFlowAsync(node, oldFlow, newFlow, getNextRid());
+ }
+ }
+ return new Status(StatusCode.NOSERVICE, "Plugin unuvailable");
+ }
+
@Override
public void flowRemoved(Node node, Flow flow) {
for (IFlowProgrammerListener l : listener) {
}
ci.println(this.addFlow(node, getSampleFlow(node)));
}
-
+
public void _modifyflow(CommandInterpreter ci) throws UnknownHostException {
Node node = null;
String nodeId = ci.nextArgument();
return flow;
}
+ /*
+ * This Request ID generator starts with 1. Each aysnc message is
+ * associated with an unique Request ID (!= 0).
+ */
+ private long getNextRid() {
+ return seq.getAndIncrement();
+ }
+
+ @Override
+ public Status sendBarrierMessage(Node node) {
+ if (this.pluginFlowProgrammer != null) {
+ if (this.pluginFlowProgrammer.get(node.getType()) != null) {
+ return this.pluginFlowProgrammer.get(node.getType())
+ .sendBarrierMessage(node);
+ }
+ }
+ return new Status(StatusCode.NOSERVICE, "Plugin unuvailable");
+ }
}
-
/*
* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
private ConcurrentMap<InetAddress, Subnet> subnets; // set of Subnets keyed by the InetAddress
private ConcurrentMap<String, SubnetConfig> subnetsConfigList;
private ConcurrentMap<Integer, SpanConfig> spanConfigList;
- private ConcurrentMap<String, SwitchConfig> nodeConfigList; // manually configured parameters for the node, like name and tier
+ private ConcurrentMap<String, SwitchConfig> nodeConfigList; // manually configured parameters for the node like name and tier
private ConcurrentMap<Long, String> configSaveEvent;
- private ConcurrentMap<Node, Map<String, Property>> nodeProps; // properties are maintained in default container only
- private ConcurrentMap<NodeConnector, Map<String, Property>> nodeConnectorProps; // properties are maintained in default container only
+ private ConcurrentMap<Node, Map<String, Property>> nodeProps; // properties are maintained in global container only
+ private ConcurrentMap<NodeConnector, Map<String, Property>> nodeConnectorProps; // properties are maintained in global container only
private ConcurrentMap<Node, Map<String, NodeConnector>> nodeConnectorNames;
private IInventoryService inventoryService;
private Set<ISwitchManagerAware> switchManagerAware = Collections
private IClusterContainerServices clusterContainerService = null;
private String containerName = null;
private boolean isDefaultContainer = true;
-
+
public enum ReasonCode {
SUCCESS("Success"), FAILURE("Failure"), INVALID_CONF(
"Invalid Configuration"), EXIST("Entry Already Exist"), CONFLICT(
try {
((ISwitchManagerAware) subAware).subnetNotify(sub, add);
} catch (Exception e) {
- log.error("Failed to notify Subnet change", e);
+ log.error("Failed to notify Subnet change {}",
+ e.getMessage());
}
}
}
try {
((ISpanAware) sa).spanUpdate(node, ports, add);
} catch (Exception e) {
- log.error("Failed to notify Span Interface change", e);
+ log.error("Failed to notify Span Interface change {}",
+ e.getMessage());
}
}
}
try {
service.modeChangeNotify(node, proactive);
} catch (Exception e) {
- log.error("Failed to notify Subnet change", e);
+ log.error("Failed to notify Subnet change {}",
+ e.getMessage());
}
}
}
}
@SuppressWarnings("deprecation")
- private void allocateCaches() {
+ private void allocateCaches() {
if (this.clusterContainerService == null) {
- log.info("un-initialized clusterContainerService, can't create cache");
+ log.warn("un-initialized clusterContainerService, can't create cache");
return;
}
try {
clusterContainerService.createCache(
- "switchmanager.subnetsConfigList", EnumSet
- .of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+ "switchmanager.subnetsConfigList",
+ EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
clusterContainerService.createCache("switchmanager.spanConfigList",
EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
clusterContainerService.createCache("switchmanager.nodeConfigList",
clusterContainerService.createCache("switchmanager.subnets",
EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
clusterContainerService.createCache(
- "switchmanager.configSaveEvent", EnumSet
- .of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+ "switchmanager.configSaveEvent",
+ EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
clusterContainerService.createCache("switchmanager.nodeProps",
EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
clusterContainerService.createCache(
- "switchmanager.nodeConnectorProps", EnumSet
- .of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+ "switchmanager.nodeConnectorProps",
+ EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
clusterContainerService.createCache(
- "switchmanager.nodeConnectorNames", EnumSet
- .of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+ "switchmanager.nodeConnectorNames",
+ EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
} catch (CacheConfigException cce) {
log.error("\nCache configuration invalid - check cache mode");
} catch (CacheExistException ce) {
@SuppressWarnings({ "unchecked", "deprecation" })
private void retrieveCaches() {
if (this.clusterContainerService == null) {
- log
- .info("un-initialized clusterContainerService, can't create cache");
+ log.info("un-initialized clusterContainerService, can't create cache");
return;
}
}
@SuppressWarnings("deprecation")
- private void destroyCaches(String container) {
+ private void destroyCaches(String container) {
if (this.clusterContainerService == null) {
- log
- .info("un-initialized clusterContainerService, can't create cache");
+ log.info("un-initialized clusterContainerService, can't create cache");
return;
}
Subnet newSubnet = new Subnet(conf);
Set<InetAddress> IPs = subnets.keySet();
if (IPs == null) {
- return new Status(StatusCode.SUCCESS, null);
+ return new Status(StatusCode.SUCCESS, null);
}
for (InetAddress i : IPs) {
Subnet existingSubnet = subnets.get(i);
private Status addRemoveSubnet(SubnetConfig conf, boolean add) {
// Valid config check
if (!conf.isValidConfig()) {
- String msg = "Invalid Subnet configuration";
+ String msg = "Invalid Subnet configuration";
log.warn(msg);
return new Status(StatusCode.BADREQUEST, msg);
}
if (add) {
// Presence check
if (subnetsConfigList.containsKey(conf.getName())) {
- return new Status(StatusCode.CONFLICT,
- "Same subnet config already exists");
+ return new Status(StatusCode.CONFLICT,
+ "Same subnet config already exists");
}
// Semantyc check
Status rc = semanticCheck(conf);
return new Status(StatusCode.NOTFOUND, "Subnet does not exist");
}
if (!conf.isValidSwitchPort(switchPorts)) {
- return new Status(StatusCode.BADREQUEST, "Invalid switchports");
+ return new Status(StatusCode.BADREQUEST, "Invalid switchports");
}
conf.addNodeConnectors(switchPorts);
// Update Configuration
SubnetConfig conf = subnetsConfigList.get(name);
if (conf == null) {
- return new Status(StatusCode.NOTFOUND, "Subnet does not exist");
+ return new Status(StatusCode.NOTFOUND, "Subnet does not exist");
}
conf.removeNodeConnectors(switchPorts);
propMap.put(tier.getName(), tier);
addNodeProps(node, propMap);
- log.info("Set Node {}'s Mode to {}", nodeId, cfgObject
- .getMode());
+ log.info("Set Node {}'s Mode to {}", nodeId,
+ cfgObject.getMode());
if (modeChange) {
notifyModeChange(node, cfgObject.isProactive());
}
}
} catch (Exception e) {
- log.debug("updateSwitchConfig: {}", e);
+ log.debug("updateSwitchConfig: {}", e.getMessage());
}
}
public Status addSpanConfig(SpanConfig conf) {
// Valid config check
if (!conf.isValidConfig()) {
- String msg = "Invalid Span configuration";
+ String msg = "Invalid Span configuration";
log.warn(msg);
return new Status(StatusCode.BADREQUEST, msg);
}
// Presence check
if (spanConfigList.containsKey(conf.hashCode())) {
- return new Status(StatusCode.CONFLICT, "Same span config exists");
+ return new Status(StatusCode.CONFLICT, "Same span config exists");
}
// Update database and notify clients
String nodeId = node.toString();
for (SwitchConfig conf : nodeConfigList.values()) {
if (conf.getNodeId().equals(nodeId)) {
- Property description = new Description(conf.getNodeDescription());
+ Property description = new Description(
+ conf.getNodeDescription());
propMap.put(description.getName(), description);
Property tier = new Tier(Integer.parseInt(conf.getTier()));
propMap.put(tier.getName(), tier);
// notify node listeners
notifyNode(node, UpdateType.ADDED, propMap);
-
+
// notify proactive mode forwarding
if (proactiveForwarding) {
- notifyModeChange(node, true);
+ notifyModeChange(node, true);
}
}
Set<Node> nodes = getNodes();
if (nodes != null) {
for (Node node : nodes) {
- if (id.equals((Long)node.getID())) {
+ if (id.equals((Long) node.getID())) {
return node;
}
}
/*
* Returns a copy of a list of properties for a given node
- *
+ *
* (non-Javadoc)
- * @see org.opendaylight.controller.switchmanager.ISwitchManager#getNodeProps(org.opendaylight.controller.sal.core.Node)
+ *
+ * @see
+ * org.opendaylight.controller.switchmanager.ISwitchManager#getNodeProps
+ * (org.opendaylight.controller.sal.core.Node)
*/
@Override
public Map<String, Property> getNodeProps(Node node) {
} else {
// get it from default container
ISwitchManager defaultSwitchManager = (ISwitchManager) ServiceHelper
- .getInstance(ISwitchManager.class, GlobalConstants.DEFAULT
- .toString(), this);
+ .getInstance(ISwitchManager.class,
+ GlobalConstants.DEFAULT.toString(), this);
return defaultSwitchManager.getNodeProps(node);
}
}
public Status removeNodeProp(Node node, String propName) {
Map<String, Property> propMap = getNodeProps(node);
if (propMap != null) {
- propMap.remove(propName);
- this.nodeProps.put(node, propMap);
+ propMap.remove(propName);
+ this.nodeProps.put(node, propMap);
}
return new Status(StatusCode.SUCCESS, null);
}
Set<NodeConnector> nodeConnectorSet = new HashSet<NodeConnector>();
for (NodeConnector nodeConnector : nodeConnectorProps.keySet()) {
- if (((Long) nodeConnector.getNode().getID())
- .longValue() != (Long) node.getID())
+ if (((Long) nodeConnector.getNode().getID()).longValue() != (Long) node
+ .getID())
continue;
if (isNodeConnectorEnabled(nodeConnector))
nodeConnectorSet.add(nodeConnector);
Set<NodeConnector> nodeConnectorSet = new HashSet<NodeConnector>();
for (NodeConnector nodeConnector : nodeConnectorProps.keySet()) {
- if (((Long) nodeConnector.getNode().getID())
- .longValue() != (Long) node.getID())
+ if (((Long) nodeConnector.getNode().getID()).longValue() != (Long) node
+ .getID())
continue;
nodeConnectorSet.add(nodeConnector);
}
}
/*
- * testing utility function which assumes we are dealing with OF Node nodeconnectors only
+ * testing utility function which assumes we are dealing with OF Node
+ * nodeconnectors only
*/
@SuppressWarnings("unused")
private Set<Long> getEnabledNodeConnectorIds(Node node) {
} else {
// get it from default container
ISwitchManager defaultSwitchManager = (ISwitchManager) ServiceHelper
- .getInstance(ISwitchManager.class, GlobalConstants.DEFAULT
- .toString(), this);
+ .getInstance(ISwitchManager.class,
+ GlobalConstants.DEFAULT.toString(), this);
return defaultSwitchManager.getNodeConnectorProps(nodeConnector);
}
}
/**
* Adds a node connector and its property if any
*
- * @param nodeConnector {@link org.opendaylight.controller.sal.core.NodeConnector}
- * @param propName name of {@link org.opendaylight.controller.sal.core.Property}
+ * @param nodeConnector
+ * {@link org.opendaylight.controller.sal.core.NodeConnector}
+ * @param propName
+ * name of {@link org.opendaylight.controller.sal.core.Property}
* @return success or failed reason
*/
@Override
- public Status addNodeConnectorProp(NodeConnector nodeConnector, Property prop) {
+ public Status addNodeConnectorProp(NodeConnector nodeConnector,
+ Property prop) {
Map<String, Property> propMap = getNodeConnectorProps(nodeConnector);
if (propMap == null) {
propMap = new HashMap<String, Property>();
}
- // Just add the nodeConnector if prop is not available (in a non-default container)
+ // Just add the nodeConnector if prop is not available (in a non-default
+ // container)
if (prop == null) {
nodeConnectorProps.put(nodeConnector, propMap);
return new Status(StatusCode.SUCCESS, null);
/**
* Removes one property of a node connector
*
- * @param nodeConnector {@link org.opendaylight.controller.sal.core.NodeConnector}
- * @param propName name of {@link org.opendaylight.controller.sal.core.Property}
+ * @param nodeConnector
+ * {@link org.opendaylight.controller.sal.core.NodeConnector}
+ * @param propName
+ * name of {@link org.opendaylight.controller.sal.core.Property}
* @return success or failed reason
*/
@Override
- public Status removeNodeConnectorProp(NodeConnector nodeConnector, String propName) {
+ public Status removeNodeConnectorProp(NodeConnector nodeConnector,
+ String propName) {
Map<String, Property> propMap = getNodeConnectorProps(nodeConnector);
if (propMap == null) {
- /* Nothing to remove */
+ /* Nothing to remove */
return new Status(StatusCode.SUCCESS, null);
}
/**
* Removes all the properties of a node connector
*
- * @param nodeConnector {@link org.opendaylight.controller.sal.core.NodeConnector}
+ * @param nodeConnector
+ * {@link org.opendaylight.controller.sal.core.NodeConnector}
* @return success or failed reason
*/
@Override
/**
* Function called by the dependency manager when all the required
* dependencies are satisfied
- *
+ *
*/
void init(Component c) {
Dictionary<?, ?> props = c.getServiceProperties();
if (props != null) {
this.containerName = (String) props.get("containerName");
- log.trace("Running containerName:" + this.containerName);
+ log.trace("Running containerName: {}", this.containerName);
} else {
// In the Global instance case the containerName is empty
this.containerName = "";
}
/**
- * Function called by the dependency manager when at least one
- * dependency become unsatisfied or when the component is shutting
- * down because for example bundle is being stopped.
- *
+ * Function called by the dependency manager when at least one dependency
+ * become unsatisfied or when the component is shutting down because for
+ * example bundle is being stopped.
+ *
*/
void destroy() {
shutDown();
}
/**
- * Function called by dependency manager after "init ()" is called
- * and after the services provided by the class are registered in
- * the service registry
- *
+ * Function called by dependency manager after "init ()" is called and after
+ * the services provided by the class are registered in the service registry
+ *
*/
void start() {
// OSGI console
}
/**
- * Function called after registered the
- * service in OSGi service registry.
+ * Function called after registered the service in OSGi service registry.
*/
void started() {
// solicit for existing inventories
}
/**
- * Function called by the dependency manager before the services
- * exported by the component are unregistered, this will be
- * followed by a "destroy ()" calls
- *
+ * Function called by the dependency manager before the services exported by
+ * the component are unregistered, this will be followed by a "destroy ()"
+ * calls
+ *
*/
void stop() {
}
return;
}
for (Node node : nodeSet) {
- Description desc = ((Description) getNodeProp(node, Description.propertyName));
+ Description desc = ((Description) getNodeProp(node,
+ Description.propertyName));
Tier tier = ((Tier) getNodeProp(node, Tier.TierPropName));
String nodeName = (desc == null) ? "" : desc.getValue();
int tierNum = (tier == null) ? 0 : tier.getValue();
- ci.println(node + " " + node.getType()
- + " " + nodeName + " " + tierNum);
+ ci.println(node + " " + node.getType() + " "
+ + nodeName + " " + tierNum);
}
ci.println("Total number of Nodes: " + nodeSet.size());
}
}
ci.println(nodeConnector
- + " "
- + ((nodeConnectorName == null) ? ""
- : nodeConnectorName) + "("
- + nodeConnector.getID() + ")");
+ + " "
+ + ((nodeConnectorName == null) ? "" : nodeConnectorName)
+ + "(" + nodeConnector.getID() + ")");
}
- ci.println("Total number of NodeConnectors: " + nodeConnectorSet.size());
+ ci.println("Total number of NodeConnectors: "
+ + nodeConnectorSet.size());
}
}
@Override
public boolean isSpecial(NodeConnector p) {
- if (p.getType().equals(NodeConnectorIDType.CONTROLLER) ||
- p.getType().equals(NodeConnectorIDType.ALL) ||
- p.getType().equals(NodeConnectorIDType.SWSTACK) ||
- p.getType().equals(NodeConnectorIDType.HWPATH)) {
+ if (p.getType().equals(NodeConnectorIDType.CONTROLLER)
+ || p.getType().equals(NodeConnectorIDType.ALL)
+ || p.getType().equals(NodeConnectorIDType.SWSTACK)
+ || p.getType().equals(NodeConnectorIDType.HWPATH)) {
return true;
}
return false;
return saveSwitchConfig();
}
- /**
- * Creates a Name/Tier/Bandwidth Property object based on given property
- * name and value. Other property types are not supported yet.
- *
- * @param propName Name of the Property
- * @param propValue Value of the Property
- * @return {@link org.opendaylight.controller.sal.core.Property}
- */
- @Override
- public Property createProperty(String propName, String propValue) {
- if (propName == null) {
- log.debug("propName is null");
- return null;
- }
- if (propValue == null) {
- log.debug("propValue is null");
- return null;
- }
-
- try {
- if (propName.equalsIgnoreCase(Description.propertyName)) {
- return new Description(propValue);
- } else if (propName.equalsIgnoreCase(Tier.TierPropName)) {
- int tier = Integer.parseInt(propValue);
- return new Tier(tier);
- } else if (propName.equalsIgnoreCase(Bandwidth.BandwidthPropName)) {
- long bw = Long.parseLong(propValue);
- return new Bandwidth(bw);
- } else {
- log.debug("Not able to create {} property", propName);
- }
- } catch (Exception e) {
- log.debug(e.getMessage());
- }
-
- return null;
- }
-
- @Override
- public String getNodeDescription(Node node) {
- // Check first if user configured a name
+ /**
+ * Creates a Name/Tier/Bandwidth Property object based on given property
+ * name and value. Other property types are not supported yet.
+ *
+ * @param propName
+ * Name of the Property
+ * @param propValue
+ * Value of the Property
+ * @return {@link org.opendaylight.controller.sal.core.Property}
+ */
+ @Override
+ public Property createProperty(String propName, String propValue) {
+ if (propName == null) {
+ log.debug("propName is null");
+ return null;
+ }
+ if (propValue == null) {
+ log.debug("propValue is null");
+ return null;
+ }
+
+ try {
+ if (propName.equalsIgnoreCase(Description.propertyName)) {
+ return new Description(propValue);
+ } else if (propName.equalsIgnoreCase(Tier.TierPropName)) {
+ int tier = Integer.parseInt(propValue);
+ return new Tier(tier);
+ } else if (propName.equalsIgnoreCase(Bandwidth.BandwidthPropName)) {
+ long bw = Long.parseLong(propValue);
+ return new Bandwidth(bw);
+ } else {
+ log.debug("Not able to create {} property", propName);
+ }
+ } catch (Exception e) {
+ log.debug("createProperty caught exception {}", e.getMessage());
+ }
+
+ return null;
+ }
+
+ @Override
+ public String getNodeDescription(Node node) {
+ // Check first if user configured a name
SwitchConfig config = getSwitchConfig(node.toString());
if (config != null) {
- String configuredDesc = config.getNodeDescription();
- if (configuredDesc != null && !configuredDesc.isEmpty()) {
- return configuredDesc;
- }
+ String configuredDesc = config.getNodeDescription();
+ if (configuredDesc != null && !configuredDesc.isEmpty()) {
+ return configuredDesc;
+ }
}
-
+
// No name configured by user, get the node advertised name
- Description desc = (Description) getNodeProp(node, Description.propertyName);
- return (desc == null /*|| desc.getValue().equalsIgnoreCase("none")*/) ?
- "" : desc.getValue();
+ Description desc = (Description) getNodeProp(node,
+ Description.propertyName);
+ return (desc == null /* || desc.getValue().equalsIgnoreCase("none") */) ? ""
+ : desc.getValue();
}
}