在之前的学习中,我们已经能实现简单的ryu app,使交换机实现自学习功能。
对初学者来讲,之前对ryu app的解析也许还存在一些困难,因为他们对openflow协议还不够熟悉。不过这不要紧。阅读openflow官方文档和ryu官方文档都能使你慢慢地去理解、消化相关的知识,发现其中的奥妙。
这里我介绍一下我们的学习资料,在编码的过程中学习是学习的最佳途径。所以我们可以来动手写一个app。
题目
假如你有一个笔友遍天下爱写信的朋友叫李华,她生活在1972年的UCLA,希望通过ARPAnet(世界第一个数据包交换网络,互联网的鼻祖,接入了25个研究机构,共计55条链路。具体拓扑见下图)发送一封Email给位于MIT的李明同学,现在需要你借助Ryu控制器编写Ryu APP帮助她
- 为减少网络中节点的中转,希望找到一条从UCLA到MIT跳数最少的连接,输出经过的路线
- 为了尽快发送Email,希望能找到一条从UCLA到MIT时延最短的连接,输出经过的路线及总的时延,利用Ping包的RTT验证你的结果(此问题选做)
说明
-
上述拓扑为ARPAnet1972.3,源自The Internet Zoo, 借助assessing-mininet转化成Mininet拓扑,做了一些修改(加入时延,修改名称等)作为实验拓扑
-
上述拓扑中存在环路,你需要解决ARP包的洪泛问题,一种解决思路是:我们通过Ryu的API可以发现全局的拓扑信息,可以将交换机的端口信息记录下来,当控制器收到一个未学习的Arp Request时,直接发给所有交换机连接主机的那些端口,这样我们可以减少数据包在网络中的无意义的洪泛(减少了在交换机与交换机间的洪泛)
-
Ryu通过LLDP报文发现拓扑中的交换机,主机发现则需要主机主动发包,相关API的使用参考如下:
from ryu.base import app_manager
from ryu.ofproto import ofproto_v1_3
from ryu.controller.handler import set_ev_cls
from ryu.controller.handler import MAIN_DISPATCHER, CONFIG_DISPATCHER
from ryu.controller import ofp_event
from ryu.lib.packet import packet
from ryu.lib.packet import ethernet
from ryu.lib import hub
from ryu.topology.api import get_all_host, get_all_link, get_all_switch
class NetworkAwareness(app_manager.RyuApp):
OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
def __init__(self, *args, **kwargs):
super(NetworkAwareness, self).__init__(*args, **kwargs)
self.dpid_mac_port = {
}
self.topo_thread = hub.spawn(self._get_topology)
def add_flow(self, datapath, priority, match, actions):
dp = datapath
ofp = dp.ofproto
parser = dp.ofproto_parser
inst = [parser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, actions