2

我目前正在使用 OpenVSwitch 和 Ryu SDN 控制器框架建立一个测试平台。OVS 在 linux 上运行,具有三个端口(包括内部端口),如以下输出所示:

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

当使用以下代码片段(最小的工作示例)连接新交换机时,我设法得到通知:

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)

当所示开关连接时,控制器正确打印Router Munic has joined!。但是,用于获取有关可用端口信息的代码片段不起作用。您知道如何获取 ryu 中的可用端口吗?代码片段来自这个问题

背景:OVS 有两个物理端口,一个连接到“外部”网络,另一个连接到“内部”网络。我不仅需要知道哪些端口可用,我还需要知道哪个端口是哪个。任何想法如何解决这个问题?提前致谢!

4

1 回答 1

2

根据我的理解,您可以将事件设置为在不同阶段接收。set_ev_cls 的第二个参数表示开关的状态。如果您想在 Ryu 和交换机之间的协商完成之前忽略 packet_in 消息,请使用 MAIN_DISPATCHER。换句话说,使用 MAIN_DISPATCHER 意味着只有在协商完成后才调用此函数。

有4个谈判阶段:

  • HANDSHAKE_DISPATCHER -> 发送并等待 hello 消息
  • CONFIG_DISPATCHER -> 版本协商并发送功能请求消息
  • MAIN_DISPATCHER -> Switch-features 消息接收和发送 set-config 消息
  • DEAD_DISPATCHER -> 与对等方断开连接。或由于某些错误而断开连接。

有关详细信息,请参阅Ryu API

回到你的问题,一个可能的原因是你正在使用 CONFIG_DISPATCHER。将其更改为 MAIN_DISPATCHER 并查看它是否有效。

另外,请确保将 a 发送OFPPortDescStatsRequest到交换机。EventOFPPortDescStatsReply因为除非请求,否则我认为不会生成开关。您需要一个生成开关请求的函数。我觉得这会修复你的代码。这是函数:(但是,我建议在我的 github 中查看此文件)。

def send_port_desc_stats_request(self, datapath):
    ofp_parser = datapath.ofproto_parser

    req = ofp_parser.OFPPortDescStatsRequest(datapath, 0)
    datapath.send_msg(req)

事件EventOFPPortStatsReplyEventOFPPortDescStatsReply可能有用。我像这样使用它们。

我的github中有一个教程,我在那里使用了几个事件。上面的函数在那里定义和解释。

于 2015-07-01T16:04:09.970 回答