RYU3.16 GUI安装与Topology模块分析

最近很多SDN研究人员问起如何安装RYU的GUI,网上也有一些教程。但是由于RYU版本问题,导致安装没有成功。本篇博文将介绍RYU3.16版本下如何安装GUI,以及对RYU拓扑模块进行简单分析。

安装GUI

Linton的博客已经有详细介绍,我在这里将一些可能出现问题的地方再提醒一次。

第一步:依赖安装及修改代码

建议查看Linton的博客,比较简单,不赘述。

第二步:运行相关组建

Shell

ryu-manager --verbose --observe-links app/simple_switch_13.py ryu.topology.switches ryu.app.rest_topology ryu.app.ofctl_rest

运行截图如下:

进入到gui目录,运行controller.py文件。

打开浏览器,访问http://127.0.0.1:8000页面。查看到connected to 127.0.0.1:8080信息则为连接成功。

Note that: 如果没有显示connected to 127.0.0.1:8000等信息,而显示Disconnected, 那么需要重新启动RYU的相关APP,再刷新网页,重新链接。运行controller.py的终端不需要动。

若连接成功,启动mininet与控制器连接,则可发现网页逐步在显示网络拓扑,点击交换机图标可查看详细信息。

众多网友表示3.19+版本无法成功使用GUI,可参考:RYU3.20 GUI DOC 进行安装使用。

TOPOLOGY源码分析

有一个小伙伴已经在我之前发布了详细的代码介绍,我不再赘述,大家有兴趣的可以前往查看:Ryu拓扑发现原理分析

在topology目录中,switches.py最重要。在switches.py文件中,核心的类是class Switches。

在Switches类中,我们仅仅需要关注几个重要的函数即可将大体的拓扑发现逻辑理清。

初始化函数初始化了一些重要的内容,如dps,ports,links等。并将lldp_loop和link_loop这两个函数加入线程(协程)。

此函数用于解析LLDP报文,从而提取出对应的信息,得到link信息。

调用了send_lldp_packet函数,循环发送LLDP报文的函数。

实时检测link事件,及时发现拓扑变化,生产对应的event,并通过send_event_to_observers提供和观察者。

使用Switches模块

在实验过程中,实验人员往往需要得到网络拓扑的信息,不仅仅是dpid,link,port这些零散的元素,而是一张图。这张图往往由邻接矩阵或关联矩阵。所以一下的内容将介绍如何将dpid,link等信息转化成邻接矩阵和关联矩阵,以便后续的算路算法使用。

在你开发的模块中,将Switches作为context加载,并在__init__函数中将其赋值给某一变量。

Shell

_CONTEXTS = {'switches': switches.Switches }

def __init__(self, *args, **kwargs):

super(yourapp, self).__init__(*args, **kwargs)

self.switches = kwargs['switches']

self.threads =

self.threads.extend([hub.spawn(self._link_monitor),])

self.threads用于保存线程。将_link_monitor函数作为执行体,加入线程执行。函数简单定义如下:

Shell

def _link_monitor(self):

while(self.is_active):

if self.links != self.dp_tracker.links.keys:

self.dps = self.dp_tracker.dps

self.links = self.dp_tracker.links.keys

hub.sleep(1)

从_link_monitor函数中可以获取到dps,links等数据。这些数据需要整理存储,以便使用,get_graph函数就是用于将数据存储在图中的函数:定义函数get_graph,函数返回值是两张图,其中图graph_cap记录两个交换机之间的链路能力,图graph_port则记录的是从src到dst的源端口,目的端口信息保存在图的对称节点上。详细代码如下:

Shell

def get_graph(self):

graph_cap = {}

graph_port = {}

for dpid in self.dps.keys:

for link in self.links:

if link.src.dpid == dpid:

graph_cap.setdefault(dpid, {})

graph_port.setdefault(dpid, {})

neighbor = link.dst.dpid

capacity = link.dst.curr_speed

graph_cap[dpid][neighbor] = capacity

graph_port[dpid][neighbor] = link.src.port_no

return graph_cap, graph_port

至此,网络拓扑图生成完毕。在运行最短路径或者其他的路径计算算法时,可使用get_graph返回的数据。

总结

一直以来做实验并不需要可视化拓扑界面,直到最近发现许多研究者频繁提问,才想起来尝试这个实验。但事实上,我觉得Switches模块的使用是一个更重要的内容。很多情况下,我们需要的是原始的数据,而不是展示出来的界面。本文内容比较简单,希望能帮助到一些SDN学习者。

作者简介: 李呈,2014/09-至今,北京邮电大学网络技术研究院 网络与交换技术国家重点实验室攻读硕士研究生

原文链接:,转发请注明来源!