Reputation: 1664
I am currently setting up a testbed using the OpenVSwitch and the Ryu SDN Controller framework. The OVS is running on linux, and has three ports (including the internal port), as can be seen in the following output:
root@MOF:~# ovs-ofctl -O OpenFlow13 show br0
OFPT_FEATURES_REPLY (OF1.3) (xid=0x2): dpid:aaaaaaaaaaaaaa21
n_tables:254, n_buffers:256
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS
OFPST_PORT_DESC reply (OF1.3) (xid=0x3):
6(eth1): addr:00:50:56:82:dc:83
config: 0
state: 0
current: 10GB-FD COPPER
advertised: COPPER
supported: 1GB-FD 10GB-FD COPPER
speed: 10000 Mbps now, 10000 Mbps max
10(eth2): addr:00:50:56:82:29:cb
config: 0
state: 0
current: 10GB-FD COPPER
advertised: COPPER
supported: 1GB-FD 10GB-FD COPPER
speed: 10000 Mbps now, 10000 Mbps max
LOCAL(br0): addr:00:50:56:82:29:cb
config: PORT_DOWN
state: LINK_DOWN
speed: 0 Mbps now, 0 Mbps max
OFPT_GET_CONFIG_REPLY (OF1.3) (xid=0x5): frags=normal miss_send_len=0
I managed to get notified when new switches connect using the following code snippet (minimal working example):
class MscApp(app_manager.RyuApp):
OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
_CONTEXTS = {
'dpset': dpset.DPSet,
}
def __init__(self, *args, **kwargs):
super(MscApp, self).__init__(*args, **kwargs)
self.dpset = kwargs['dpset']
# Initiate datapath array
self.datapaths = {
0xAAAAAAAAAAAAAA21: {
'name': 'Munic',
}
}
@set_ev_cls(ofp_event.EventOFPDescStatsReply, MAIN_DISPATCHER)
def desc_stats_reply_handler(self,msg):
ofp = msg.datapath.ofproto
body = ev.msg.body
self.logger.info('OFPDescStatsReply received: '
'mfr_desc=%d hw_desc=%s sw_desc=%s '
'serial_num=%s dp_desc=%s ',
body.mfr_desc, body.hw_desc, body.sw_desc,
body.serial_num, body.dp_desc)
@set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
def switch_features_handler(self, ev):
datapath = ev.msg.datapath
ofproto = datapath.ofproto
parser = datapath.ofproto_parser
print 'Router %s has joined!' % self.datapaths[datapath.id]['name']
# Get available ports
req = parser.OFPPortDescStatsRequest(datapath, 0)
datapath.send_msg(req)
@set_ev_cls(event.EventLinkAdd)
def link_add(self, ev):
print ev.link.src, ev.link.dst
print self._get_hwaddr(ev.link.src.dpid, ev.link.src.port_no)
When the shown switch connects, the controller correctly prints Router Munic has joined!
. However, the code snippet to fetch information about the available ports does not work. Do you have an idea how to fetch the available ports in ryu? The code snippet is from this question.
Background: The OVS has two physical ports, one is connected to an "outside" network, the other one to an "inside" network. Not only do I need to know which ports are available, I also need to know which port is which. Any ideas how to solve this? Thanks in advance!
Upvotes: 2
Views: 2358
Reputation: 679
Based on my understanding you can set the event to be received on different phases. The second argument of set_ev_cls indicates the state of the switch. If you want to ignore packet_in messages before the negotiation between Ryu and the switch finishes use MAIN_DISPATCHER. In other words, using MAIN_DISPATCHER means this function is called only after the negotiation completes.
There are 4 negotiation phases:
See the the Ryu API for more details.
So back to your question, a possible reason is that you are using CONFIG_DISPATCHER. Change it to MAIN_DISPATCHER and see if it works.
Also, make sure you send a OFPPortDescStatsRequest
to the switch. Cause I don't think switches generate EventOFPPortDescStatsReply
unless are requested. You need a function which generates a request for a switch. I fell like this is would fix your code. Here is the function: (however, i recommend to have look at this file in my github).
def send_port_desc_stats_request(self, datapath):
ofp_parser = datapath.ofproto_parser
req = ofp_parser.OFPPortDescStatsRequest(datapath, 0)
datapath.send_msg(req)
Events EventOFPPortStatsReply
and EventOFPPortDescStatsReply
may be useful. I am using them like this.
I have a tutorial in my github, I am using several events there. The above function are defined and explained there .
Upvotes: 3