When switch sends version higher than Ryu supports, Ryu fails to negotiate.
In this case
4 = OF1.3 from switch
3 = OF1.2 from Ryu
datapath.supported_ofp_version = (3 = OF1.2,)
In such cases, we should use OF1.2 instead of error.
> Connection to controller closed because of {"localhost",6633,0,
> {unsupported_version,4}}
Reported-by: Shivaram Mysore <[email protected]>
Signed-off-by: Isaku Yamahata <[email protected]>
---
Changes v1 -> v2:
- return error when min(switch version, ryu version) isn't usable
- typo min instead of max
- minor code clean up
---
ryu/controller/ofp_handler.py | 66 +++++++++++++++++++++++++++++++++--------
1 file changed, 53 insertions(+), 13 deletions(-)
diff --git a/ryu/controller/ofp_handler.py b/ryu/controller/ofp_handler.py
index 63f888a..9c13c20 100644
--- a/ryu/controller/ofp_handler.py
+++ b/ryu/controller/ofp_handler.py
@@ -18,7 +18,6 @@ import logging
from ryu import utils
from ryu.base import app_manager
-from ryu.controller import dispatcher
from ryu.controller import ofp_event
from ryu.controller.handler import set_ev_cls
from ryu.controller.handler import HANDSHAKE_DISPATCHER, CONFIG_DISPATCHER,\
@@ -44,6 +43,15 @@ class OFPHandler(app_manager.RyuApp):
def __init__(self, *args, **kwargs):
super(OFPHandler, self).__init__(*args, **kwargs)
+ @staticmethod
+ def hello_failed(datapath, error_desc):
+ LOG.error(error_desc)
+ error_msg = datapath.ofproto_parser.OFPErrorMsg(datapath)
+ error_msg.type = datapath.ofproto.OFPET_HELLO_FAILED
+ error_msg.code = datapath.ofproto.OFPHFC_INCOMPATIBLE
+ error_msg.data = error_desc
+ datapath.send_msg(error_msg)
+
@set_ev_cls(ofp_event.EventOFPHello, HANDSHAKE_DISPATCHER)
def hello_handler(self, ev):
LOG.debug('hello ev %s', ev)
@@ -52,20 +60,52 @@ class OFPHandler(app_manager.RyuApp):
# TODO: check if received version is supported.
# pre 1.0 is not supported
- if msg.version not in datapath.supported_ofp_version:
+ # TODO: OFPHET_VERSIONBITMAP
+ usable_versions = [version for version
+ in datapath.supported_ofp_version
+ if version <= msg.version]
+ if not usable_versions:
# send the error
- error_msg = datapath.ofproto_parser.OFPErrorMsg(datapath)
- error_msg.type = datapath.ofproto.OFPET_HELLO_FAILED
- error_msg.code = datapath.ofproto.OFPHFC_INCOMPATIBLE
- error_msg.data = 'unsupported version 0x%x' % msg.version
- datapath.send_msg(error_msg)
+ error_desc = 'unsupported version 0x%x. '
+ 'If possible, set the switch to use one of the versions %s' % (
+ msg.version, datapath.supported_ofp_version.keys())
+ self.hello_failed(error_desc)
return
-
- # should we again send HELLO with the version that the switch
- # supports?
- # msg.version != datapath.ofproto.OFP_VERSION:
-
- datapath.set_version(msg.version)
+ version = max(usable_versions)
+ if version != min(msg.version, datapath.ofproto.OFP_VERSION):
+ # The version of min(msg.version, datapath.ofproto.OFP_VERSION)
+ # should be used according to the spec. But we can't.
+ # So log it and use max(usable_versions) with the hope that
+ # the switch is able to understand lower version.
+ # e.g.
+ # OF 1.1 from switch
+ # OF 1.2 from Ryu and supported_ofp_version = (1.0, 1.2)
+ # In this case, 1.1 should be used according to the spec,
+ # but 1.1 can't be used.
+ #
+ # OF1.3.1 6.3.1
+ # Upon receipt of this message, the recipient must
+ # calculate the OpenFlow protocol version to be used. If
+ # both the Hello message sent and the Hello message
+ # received contained a OFPHET_VERSIONBITMAP hello element,
+ # and if those bitmaps have some common bits set, the
+ # negotiated version must be the highest version set in
+ # both bitmaps. Otherwise, the negotiated version must be
+ # the smaller of the version number that was sent and the
+ # one that was received in the version fields. If the
+ # negotiated version is supported by the recipient, then
+ # the connection proceeds. Otherwise, the recipient must
+ # reply with an OFPT_ERROR message with a type field of
+ # OFPET_HELLO_FAILED, a code field of OFPHFC_INCOMPATIBLE,
+ # and optionally an ASCII string explaining the situation
+ # in data, and then terminate the connection.
+ error_desc = 'no compatible version found: '
+ 'switch 0x%x controller 0x%x, but found usable 0x%x. '
+ 'If possible, set the switch to use OF version 0x%x' % (
+ msg.version, datapath.ofproto.OFP_VERSION, version, version)
+ self.hello_failed(error_desc)
+ return
+ datapath.set_version(version)
# now send feature
features_reqeust = datapath.ofproto_parser.OFPFeaturesRequest(datapath)
--
1.7.10.4
------------------------------------------------------------------------------
LogMeIn Rescue: Anywhere, Anytime Remote support for IT. Free Trial
Remotely access PCs and mobile devices and provide instant support
Improve your efficiency, and focus on delivering more value-add services
Discover what IT Professionals Know. Rescue delivers
http://p.sf.net/sfu/logmein_12329d2d
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel