2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.controller.protocol_plugin.openflow.core.internal;
11 import java.nio.channels.SelectionKey;
12 import java.nio.channels.Selector;
13 import java.nio.channels.SocketChannel;
14 import java.nio.channels.spi.SelectorProvider;
15 import java.util.ArrayList;
16 import java.util.Comparator;
17 import java.util.Date;
18 import java.util.HashMap;
19 import java.util.Iterator;
20 import java.util.List;
23 import java.util.Timer;
24 import java.util.TimerTask;
25 import java.util.concurrent.Callable;
26 import java.util.concurrent.ConcurrentHashMap;
27 import java.util.concurrent.ExecutorService;
28 import java.util.concurrent.Executors;
29 import java.util.concurrent.Future;
30 import java.util.concurrent.PriorityBlockingQueue;
31 import java.util.concurrent.RejectedExecutionException;
32 import java.util.concurrent.TimeUnit;
33 import java.util.concurrent.atomic.AtomicInteger;
35 import org.opendaylight.controller.protocol_plugin.openflow.core.IController;
36 import org.opendaylight.controller.protocol_plugin.openflow.core.IMessageReadWrite;
37 import org.opendaylight.controller.protocol_plugin.openflow.core.ISwitch;
38 import org.openflow.protocol.OFBarrierReply;
39 import org.openflow.protocol.OFBarrierRequest;
40 import org.openflow.protocol.OFEchoReply;
41 import org.openflow.protocol.OFEchoRequest;
42 import org.openflow.protocol.OFError;
43 import org.openflow.protocol.OFFeaturesReply;
44 import org.openflow.protocol.OFFlowMod;
45 import org.openflow.protocol.OFGetConfigReply;
46 import org.openflow.protocol.OFMatch;
47 import org.openflow.protocol.OFMessage;
48 import org.openflow.protocol.OFPhysicalPort;
49 import org.openflow.protocol.OFPhysicalPort.OFPortConfig;
50 import org.openflow.protocol.OFPhysicalPort.OFPortFeatures;
51 import org.openflow.protocol.OFPhysicalPort.OFPortState;
52 import org.openflow.protocol.OFPort;
53 import org.openflow.protocol.OFPortStatus;
54 import org.openflow.protocol.OFPortStatus.OFPortReason;
55 import org.openflow.protocol.OFSetConfig;
56 import org.openflow.protocol.OFStatisticsReply;
57 import org.openflow.protocol.OFStatisticsRequest;
58 import org.openflow.protocol.OFType;
59 import org.openflow.protocol.factory.BasicFactory;
60 import org.openflow.util.HexString;
61 import org.slf4j.Logger;
62 import org.slf4j.LoggerFactory;
65 public class SwitchHandler implements ISwitch {
66 private static final Logger logger = LoggerFactory.getLogger(SwitchHandler.class);
67 private static final int SWITCH_LIVENESS_TIMER = 5000;
68 private static final int switchLivenessTimeout = getSwitchLivenessTimeout();
69 private final int MESSAGE_RESPONSE_TIMER = 2000;
71 private final String instanceName;
72 private final ISwitch thisISwitch;
73 private final IController core;
75 private Integer buffers;
76 private Integer capabilities;
78 private Integer actions;
79 private Selector selector;
80 private final SocketChannel socket;
81 private final BasicFactory factory;
82 private final AtomicInteger xid;
83 private SwitchState state;
84 private Timer periodicTimer;
85 private final Map<Short, OFPhysicalPort> physicalPorts;
86 private final Map<Short, Integer> portBandwidth;
87 private final Date connectedDate;
88 private Long lastMsgReceivedTimeStamp;
89 private Boolean probeSent;
90 private final ExecutorService executor;
91 private final ConcurrentHashMap<Integer, Callable<Object>> messageWaitingDone;
92 private boolean running;
93 private IMessageReadWrite msgReadWriteService;
94 private Thread switchHandlerThread;
95 private Integer responseTimerValue;
96 private PriorityBlockingQueue<PriorityMessage> transmitQ;
97 private Thread transmitThread;
99 private enum SwitchState {
100 NON_OPERATIONAL(0), WAIT_FEATURES_REPLY(1), WAIT_CONFIG_REPLY(2), OPERATIONAL(3);
104 private SwitchState(int value) {
108 @SuppressWarnings("unused")
114 public SwitchHandler(Controller core, SocketChannel sc, String name) {
115 this.instanceName = name;
116 this.thisISwitch = this;
118 this.buffers = (int) 0;
119 this.capabilities = (int) 0;
120 this.tables = (byte) 0;
121 this.actions = (int) 0;
124 this.factory = new BasicFactory();
125 this.connectedDate = new Date();
126 this.lastMsgReceivedTimeStamp = connectedDate.getTime();
127 this.physicalPorts = new HashMap<Short, OFPhysicalPort>();
128 this.portBandwidth = new HashMap<Short, Integer>();
129 this.state = SwitchState.NON_OPERATIONAL;
130 this.probeSent = false;
131 this.xid = new AtomicInteger(this.socket.hashCode());
132 this.periodicTimer = null;
133 this.executor = Executors.newFixedThreadPool(4);
134 this.messageWaitingDone = new ConcurrentHashMap<Integer, Callable<Object>>();
135 this.responseTimerValue = MESSAGE_RESPONSE_TIMER;
136 String rTimer = System.getProperty("of.messageResponseTimer");
137 if (rTimer != null) {
139 responseTimerValue = Integer.decode(rTimer);
140 } catch (NumberFormatException e) {
141 logger.warn("Invalid of.messageResponseTimer: {} use default({})", rTimer, MESSAGE_RESPONSE_TIMER);
146 public void start() {
148 startTransmitThread();
151 startHandlerThread();
152 } catch (Exception e) {
157 private void startHandlerThread() {
158 switchHandlerThread = new Thread(new Runnable() {
164 // wait for an incoming connection
166 Iterator<SelectionKey> selectedKeys = selector.selectedKeys().iterator();
167 while (selectedKeys.hasNext()) {
168 SelectionKey skey = selectedKeys.next();
169 selectedKeys.remove();
170 if (skey.isValid() && skey.isWritable()) {
173 if (skey.isValid() && skey.isReadable()) {
177 } catch (Exception e) {
183 switchHandlerThread.start();
186 private void stopInternal() {
187 logger.debug("{} receives stop signal",
188 (isOperational() ? HexString.toHexString(sid) : "unknown"));
194 } catch (Exception e) {
198 } catch (Exception e) {
201 msgReadWriteService.stop();
202 } catch (Exception e) {
204 logger.debug("executor shutdown now");
205 executor.shutdownNow();
207 msgReadWriteService = null;
213 if (switchHandlerThread != null) {
214 switchHandlerThread.interrupt();
216 if (transmitThread != null) {
217 transmitThread.interrupt();
222 public int getNextXid() {
223 return this.xid.incrementAndGet();
227 * This method puts the message in an outgoing priority queue with normal
228 * priority. It will be served after high priority messages. The method
229 * should be used for non-critical messages such as statistics request,
230 * discovery packets, etc. An unique XID is generated automatically and
231 * inserted into the message.
234 * The OF message to be sent
235 * @return The XID used
238 public Integer asyncSend(OFMessage msg) {
239 return asyncSend(msg, getNextXid());
242 private Object syncSend(OFMessage msg, int xid) {
243 return syncMessageInternal(msg, xid, true);
247 * This method puts the message in an outgoing priority queue with normal
248 * priority. It will be served after high priority messages. The method
249 * should be used for non-critical messages such as statistics request,
250 * discovery packets, etc. The specified XID is inserted into the message.
253 * The OF message to be Sent
255 * The XID to be used in the message
256 * @return The XID used
259 public Integer asyncSend(OFMessage msg, int xid) {
261 if (transmitQ != null) {
262 transmitQ.add(new PriorityMessage(msg, 0));
268 * This method puts the message in an outgoing priority queue with high
269 * priority. It will be served first before normal priority messages. The
270 * method should be used for critical messages such as hello, echo reply
271 * etc. An unique XID is generated automatically and inserted into the
275 * The OF message to be sent
276 * @return The XID used
279 public Integer asyncFastSend(OFMessage msg) {
280 return asyncFastSend(msg, getNextXid());
284 * This method puts the message in an outgoing priority queue with high
285 * priority. It will be served first before normal priority messages. The
286 * method should be used for critical messages such as hello, echo reply
287 * etc. The specified XID is inserted into the message.
290 * The OF message to be sent
291 * @return The XID used
294 public Integer asyncFastSend(OFMessage msg, int xid) {
296 if (transmitQ != null) {
297 transmitQ.add(new PriorityMessage(msg, 1));
302 public void resumeSend() {
304 if (msgReadWriteService != null) {
305 msgReadWriteService.resumeSend();
307 } catch (Exception e) {
313 * This method bypasses the transmit queue and sends the message over the
314 * socket directly. If the input xid is not null, the specified xid is
315 * inserted into the message. Otherwise, an unique xid is generated
316 * automatically and inserted into the message.
323 private void asyncSendNow(OFMessage msg, Integer xid) {
333 * This method bypasses the transmit queue and sends the message over the
339 private void asyncSendNow(OFMessage msg) {
340 if (msgReadWriteService == null) {
341 logger.warn("asyncSendNow: {} is not sent because Message ReadWrite Service is not available.", msg);
346 msgReadWriteService.asyncSend(msg);
347 } catch (Exception e) {
352 public void handleMessages() {
353 List<OFMessage> msgs = null;
356 if (msgReadWriteService != null) {
357 msgs = msgReadWriteService.readMessages();
359 } catch (Exception e) {
366 for (OFMessage msg : msgs) {
367 logger.trace("Message received: {}", msg);
368 this.lastMsgReceivedTimeStamp = System.currentTimeMillis();
369 OFType type = msg.getType();
372 sendFeaturesRequest();
375 OFEchoReply echoReply = (OFEchoReply) factory.getMessage(OFType.ECHO_REPLY);
377 byte []payload = ((OFEchoRequest)msg).getPayload();
378 if (payload != null && payload.length != 0 ) {
379 // the response must have the same payload as the request
380 echoReply.setPayload(payload);
381 echoReply.setLength( (short)(echoReply.getLength() + payload.length) );
384 // respond immediately
385 asyncSendNow(echoReply, msg.getXid());
387 // send features request if not sent yet
388 sendFeaturesRequest();
391 this.probeSent = false;
394 processFeaturesReply((OFFeaturesReply) msg);
396 case GET_CONFIG_REPLY:
397 // make sure that the switch can send the whole packet to the
399 if (((OFGetConfigReply) msg).getMissSendLength() == (short) 0xffff) {
400 this.state = SwitchState.OPERATIONAL;
404 processBarrierReply((OFBarrierReply) msg);
407 processErrorReply((OFError) msg);
410 processPortStatusMsg((OFPortStatus) msg);
413 processStatsReply((OFStatisticsReply) msg);
420 if (isOperational()) {
421 ((Controller) core).takeSwitchEventMsg(thisISwitch, msg);
426 private void processPortStatusMsg(OFPortStatus msg) {
427 OFPhysicalPort port = msg.getDesc();
428 if (msg.getReason() == (byte) OFPortReason.OFPPR_MODIFY.ordinal()) {
429 updatePhysicalPort(port);
430 } else if (msg.getReason() == (byte) OFPortReason.OFPPR_ADD.ordinal()) {
431 updatePhysicalPort(port);
432 } else if (msg.getReason() == (byte) OFPortReason.OFPPR_DELETE.ordinal()) {
433 deletePhysicalPort(port);
438 private void startSwitchTimer() {
439 this.periodicTimer = new Timer();
440 this.periodicTimer.scheduleAtFixedRate(new TimerTask() {
444 Long now = System.currentTimeMillis();
445 if ((now - lastMsgReceivedTimeStamp) > switchLivenessTimeout) {
447 // switch failed to respond to our probe, consider
449 logger.warn("{} sid {} is idle for too long, disconnect", socket.socket()
450 .getRemoteSocketAddress().toString().split("/")[1], (sid == 0) ? "unknown"
451 : HexString.toHexString(sid));
452 reportSwitchStateChange(false);
454 // send a probe to see if the switch is still alive
455 logger.debug("Send idle probe (Echo Request) to {}", this);
457 OFMessage echo = factory.getMessage(OFType.ECHO_REQUEST);
461 if (state == SwitchState.WAIT_FEATURES_REPLY) {
462 // send another features request
463 OFMessage request = factory.getMessage(OFType.FEATURES_REQUEST);
464 asyncFastSend(request);
466 if (state == SwitchState.WAIT_CONFIG_REPLY) {
467 // send another config request
468 OFSetConfig config = (OFSetConfig) factory.getMessage(OFType.SET_CONFIG);
469 config.setMissSendLength((short) 0xffff).setLengthU(OFSetConfig.MINIMUM_LENGTH);
470 asyncFastSend(config);
471 OFMessage getConfig = factory.getMessage(OFType.GET_CONFIG_REQUEST);
472 asyncFastSend(getConfig);
476 } catch (Exception e) {
480 }, SWITCH_LIVENESS_TIMER, SWITCH_LIVENESS_TIMER);
483 private void cancelSwitchTimer() {
484 if (this.periodicTimer != null) {
485 this.periodicTimer.cancel();
489 private void reportError(Exception e) {
491 logger.debug("Caught exception {} while switch {} is shutting down. Skip", e.getMessage(),
492 (isOperational() ? HexString.toHexString(sid) : "unknown"));
495 logger.debug("Caught exception: ", e);
497 // notify core of this error event and disconnect the switch
498 ((Controller) core).takeSwitchEventError(this);
500 // clean up some internal states immediately
504 private void reportSwitchStateChange(boolean added) {
506 ((Controller) core).takeSwitchEventAdd(this);
508 ((Controller) core).takeSwitchEventDelete(this);
513 public Long getId() {
517 private void sendFeaturesRequest() {
518 if (!isOperational() && (this.state != SwitchState.WAIT_FEATURES_REPLY)) {
519 // send feature request
520 OFMessage featureRequest = factory.getMessage(OFType.FEATURES_REQUEST);
521 asyncFastSend(featureRequest);
522 this.state = SwitchState.WAIT_FEATURES_REPLY;
527 private void processFeaturesReply(OFFeaturesReply reply) {
528 if (this.state == SwitchState.WAIT_FEATURES_REPLY) {
529 this.sid = reply.getDatapathId();
530 this.buffers = reply.getBuffers();
531 this.capabilities = reply.getCapabilities();
532 this.tables = reply.getTables();
533 this.actions = reply.getActions();
534 // notify core of this error event
535 for (OFPhysicalPort port : reply.getPorts()) {
536 updatePhysicalPort(port);
538 // config the switch to send full data packet
539 OFSetConfig config = (OFSetConfig) factory.getMessage(OFType.SET_CONFIG);
540 config.setMissSendLength((short) 0xffff).setLengthU(OFSetConfig.MINIMUM_LENGTH);
541 asyncFastSend(config);
542 // send config request to make sure the switch can handle the set
544 OFMessage getConfig = factory.getMessage(OFType.GET_CONFIG_REQUEST);
545 asyncFastSend(getConfig);
546 this.state = SwitchState.WAIT_CONFIG_REPLY;
547 // inform core that a new switch is now operational
548 reportSwitchStateChange(true);
552 private void updatePhysicalPort(OFPhysicalPort port) {
553 Short portNumber = port.getPortNumber();
554 physicalPorts.put(portNumber, port);
557 port.getCurrentFeatures()
558 & (OFPortFeatures.OFPPF_10MB_FD.getValue() | OFPortFeatures.OFPPF_10MB_HD.getValue()
559 | OFPortFeatures.OFPPF_100MB_FD.getValue()
560 | OFPortFeatures.OFPPF_100MB_HD.getValue()
561 | OFPortFeatures.OFPPF_1GB_FD.getValue()
562 | OFPortFeatures.OFPPF_1GB_HD.getValue() | OFPortFeatures.OFPPF_10GB_FD
566 private void deletePhysicalPort(OFPhysicalPort port) {
567 Short portNumber = port.getPortNumber();
568 physicalPorts.remove(portNumber);
569 portBandwidth.remove(portNumber);
573 public boolean isOperational() {
574 return ((this.state == SwitchState.WAIT_CONFIG_REPLY) || (this.state == SwitchState.OPERATIONAL));
578 public String toString() {
580 return ("Switch:" + socket.socket().getRemoteSocketAddress().toString().split("/")[1] + " SWID:" + (isOperational() ? HexString
581 .toHexString(this.sid) : "unknown"));
582 } catch (Exception e) {
583 return (isOperational() ? HexString.toHexString(this.sid) : "unknown");
589 public Date getConnectedDate() {
590 return this.connectedDate;
593 public String getInstanceName() {
598 public Object getStatistics(OFStatisticsRequest req) {
599 int xid = getNextXid();
600 StatisticsCollector worker = new StatisticsCollector(this, xid, req);
601 messageWaitingDone.put(xid, worker);
602 Future<Object> submit;
603 Object result = null;
605 submit = executor.submit(worker);
606 } catch (RejectedExecutionException re) {
607 messageWaitingDone.remove(xid);
611 result = submit.get(responseTimerValue, TimeUnit.MILLISECONDS);
613 } catch (Exception e) {
614 logger.warn("Timeout while waiting for {} replies from {}",
615 req.getType(), (isOperational() ? HexString.toHexString(sid) : "unknown"));
616 result = null; // to indicate timeout has occurred
623 public Object syncSend(OFMessage msg) {
625 logger.debug("Switch is going down, ignore syncSend");
628 int xid = getNextXid();
629 return syncSend(msg, xid);
633 * Either a BarrierReply or a OFError is received. If this is a reply for an
634 * outstanding sync message, wake up associated task so that it can continue
636 private void processBarrierReply(OFBarrierReply msg) {
637 Integer xid = msg.getXid();
638 SynchronousMessage worker = (SynchronousMessage) messageWaitingDone.remove(xid);
639 if (worker == null) {
645 private void processErrorReply(OFError errorMsg) {
646 OFMessage offendingMsg = errorMsg.getOffendingMsg();
648 if (offendingMsg != null) {
649 xid = offendingMsg.getXid();
651 xid = errorMsg.getXid();
654 * the error can be a reply to a synchronous message or to a statistic
657 Callable<?> worker = messageWaitingDone.remove(xid);
658 if (worker == null) {
661 if (worker instanceof SynchronousMessage) {
662 ((SynchronousMessage) worker).wakeup(errorMsg);
664 ((StatisticsCollector) worker).wakeup(errorMsg);
668 private void processStatsReply(OFStatisticsReply reply) {
669 Integer xid = reply.getXid();
670 StatisticsCollector worker = (StatisticsCollector) messageWaitingDone.get(xid);
671 if (worker == null) {
674 if (worker.collect(reply)) {
675 // if all the stats records are received (collect() returns true)
677 messageWaitingDone.remove(xid);
683 public Map<Short, OFPhysicalPort> getPhysicalPorts() {
684 return this.physicalPorts;
688 public OFPhysicalPort getPhysicalPort(Short portNumber) {
689 return this.physicalPorts.get(portNumber);
693 public Integer getPortBandwidth(Short portNumber) {
694 return this.portBandwidth.get(portNumber);
698 public Set<Short> getPorts() {
699 return this.physicalPorts.keySet();
703 public Byte getTables() {
708 public Integer getActions() {
713 public Integer getCapabilities() {
714 return this.capabilities;
718 public Integer getBuffers() {
723 public boolean isPortEnabled(short portNumber) {
724 return isPortEnabled(physicalPorts.get(portNumber));
728 public boolean isPortEnabled(OFPhysicalPort port) {
732 int portConfig = port.getConfig();
733 int portState = port.getState();
734 if ((portConfig & OFPortConfig.OFPPC_PORT_DOWN.getValue()) > 0) {
737 if ((portState & OFPortState.OFPPS_LINK_DOWN.getValue()) > 0) {
740 if ((portState & OFPortState.OFPPS_STP_MASK.getValue()) == OFPortState.OFPPS_STP_BLOCK.getValue()) {
747 public List<OFPhysicalPort> getEnabledPorts() {
748 List<OFPhysicalPort> result = new ArrayList<OFPhysicalPort>();
749 synchronized (this.physicalPorts) {
750 for (OFPhysicalPort port : physicalPorts.values()) {
751 if (isPortEnabled(port)) {
760 * Transmit thread polls the message out of the priority queue and invokes
761 * messaging service to transmit it over the socket channel
763 class PriorityMessageTransmit implements Runnable {
769 PriorityMessage pmsg = transmitQ.take();
770 msgReadWriteService.asyncSend(pmsg.msg);
772 * If syncReply is set to true, wait for the response back.
774 if (pmsg.syncReply) {
775 syncMessageInternal(pmsg.msg, pmsg.msg.getXid(), false);
777 } catch (InterruptedException ie) {
778 reportError(new InterruptedException("PriorityMessageTransmit thread interrupted"));
779 } catch (Exception e) {
788 * Setup and start the transmit thread
790 private void startTransmitThread() {
791 this.transmitQ = new PriorityBlockingQueue<PriorityMessage>(11, new Comparator<PriorityMessage>() {
793 public int compare(PriorityMessage p1, PriorityMessage p2) {
794 if (p2.priority != p1.priority) {
795 return p2.priority - p1.priority;
797 return (p2.seqNum < p1.seqNum) ? 1 : -1;
801 this.transmitThread = new Thread(new PriorityMessageTransmit());
802 this.transmitThread.start();
806 * Setup communication services
808 private void setupCommChannel() throws Exception {
809 this.selector = SelectorProvider.provider().openSelector();
810 this.socket.configureBlocking(false);
811 this.socket.socket().setTcpNoDelay(true);
812 this.msgReadWriteService = getMessageReadWriteService();
815 private void sendFirstHello() {
817 OFMessage msg = factory.getMessage(OFType.HELLO);
819 } catch (Exception e) {
824 private IMessageReadWrite getMessageReadWriteService() throws Exception {
825 String str = System.getProperty("secureChannelEnabled");
826 return ((str != null) && (str.trim().equalsIgnoreCase("true"))) ? new SecureMessageReadWriteService(socket,
827 selector) : new MessageReadWriteService(socket, selector);
831 * Send Barrier message synchronously. The caller will be blocked until the
832 * Barrier reply is received.
835 public Object syncSendBarrierMessage() {
836 OFBarrierRequest barrierMsg = new OFBarrierRequest();
837 return syncSend(barrierMsg);
841 * Send Barrier message asynchronously. The caller is not blocked. The
842 * Barrier message will be sent in a transmit thread which will be blocked
843 * until the Barrier reply is received.
846 public Object asyncSendBarrierMessage() {
847 if (transmitQ == null) {
848 return Boolean.FALSE;
851 OFBarrierRequest barrierMsg = new OFBarrierRequest();
852 int xid = getNextXid();
854 barrierMsg.setXid(xid);
855 transmitQ.add(new PriorityMessage(barrierMsg, 0, true));
861 * This method returns the switch liveness timeout value. If controller did
862 * not receive any message from the switch for such a long period,
863 * controller will tear down the connection to the switch.
865 * @return The timeout value
867 private static int getSwitchLivenessTimeout() {
868 String timeout = System.getProperty("of.switchLivenessTimeout");
872 if (timeout != null) {
873 rv = Integer.parseInt(timeout);
875 } catch (Exception e) {
882 * This method performs synchronous operations for a given message. If
883 * syncRequest is set to true, the message will be sent out followed by a
884 * Barrier request message. Then it's blocked until the Barrier rely arrives
885 * or timeout. If syncRequest is false, it simply skips the message send and
886 * just waits for the response back.
893 * If set to true, the message the message will be sent out
894 * followed by a Barrier request message. If set to false, it
895 * simply skips the sending and just waits for the Barrier reply.
898 private Object syncMessageInternal(OFMessage msg, int xid, boolean syncRequest) {
899 SynchronousMessage worker = new SynchronousMessage(this, xid, msg, syncRequest);
900 messageWaitingDone.put(xid, worker);
901 Object result = null;
902 Boolean status = false;
903 Future<Object> submit;
905 submit = executor.submit(worker);
906 } catch (RejectedExecutionException re) {
907 messageWaitingDone.remove(xid);
911 result = submit.get(responseTimerValue, TimeUnit.MILLISECONDS);
912 messageWaitingDone.remove(xid);
913 if (result == null) {
914 // if result is null, then it means the switch can handle this
915 // message successfully
916 // convert the result into a Boolean with value true
918 // logger.debug("Successfully send " +
919 // msg.getType().toString());
922 // if result is not null, this means the switch can't handle
924 // the result if OFError already
925 if (logger.isDebugEnabled()) {
926 logger.debug("Send {} failed --> {}", msg.getType(), (result));
930 } catch (Exception e) {
931 logger.warn("Timeout while waiting for {} reply", msg.getType().toString());
932 // convert the result into a Boolean with value false
941 public void deleteAllFlows() {
942 logger.trace("deleteAllFlows on switch {}", HexString.toHexString(this.sid));
943 OFMatch match = new OFMatch().setWildcards(OFMatch.OFPFW_ALL);
944 OFFlowMod flowMod = (OFFlowMod) factory.getMessage(OFType.FLOW_MOD);
945 flowMod.setMatch(match).setCommand(OFFlowMod.OFPFC_DELETE).setOutPort(OFPort.OFPP_NONE)
946 .setLength((short) OFFlowMod.MINIMUM_LENGTH);
947 asyncFastSend(flowMod);