怎么编程
- 编程不是顺序地写代码语句
- 看懂逻辑后一块一块的写
- 而是从宏观到微观,从架构到实现立体工程
编程总体思路
- 明确问题
- 设计解决方案
- 确定具体的技术方案
- 部署实施
- 验证方案
- 优化
Ryu应用开发:Hub/集线器
Hub/集线器
- 如何实现软件定义的集线器?
- 通过控制器来实现集线器算法(泛洪),然后指导数据平面实现集线器操作
- 控制器选用Ryu数据平面通过Mininet模拟
- 在控制器上编程开发集线器应用,创建实验网络为验证证反感做准备
- 运行程序,调试程序,验证程序
- 验证成功后,优化程序
Hub/集线器原理
- 数据包从一个端口进去,其余的端口出去
Hub/集线器实现部署(Ryu控制器API的学习和使用)
- 在ryu/app下创建hub.py
- 编写集线器的应用
# ryu/base 文件夹下 app_manager.py 文件
from ryu.base import app_manager
from ryu.ofproto import ofproto_v1_3
from ryu.controller import ofp_event
from ryu.controller.handler import MAIN_DISPATCHER,CONFIG_DISPATCHER
from ryu.controller.handler import set_ev_cls
# 集线器
# 下面一行是Hub继承app_manager.RyuApp的语法
class Hub(app_manager.RyuApp):
***介绍一下下面代码是做什么的***
# OFP OpenFlowProtocol,这里明确一下它的版本,是 ofproto_v1_3 类下的 OFP_VERSION 常数 Ox04,版本1.3
OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
# _init_ 是构造方法,self是必须是第一个参数,后面的自定义
# 构造方法:实例化对象的时候执行的方法
def _init_(self,*args,**kwargs):
super(Hub,self)._init_(*args,**kwargs)
# 处理交换机的连接
# 监听交换机连接的事件,从CONFIG状态开始监听
@set_ev_cls(ofp_event.EventOFPSwitchFeatures,CONFIG_DISPATCHER)
def switch_features_handler(self,ev):
# 对数据进行解析
# datapath 数据平面通道,可以等同于网桥
# 获取三个必要的参数
# ofproto openflow的版本
# ofp_parser 是对应版本的解析
datapath = ev.msg.datapath
ofproto = datapath.ofproto
ofp_parser = datapath.ofproto_parser
# 接收交换机连接后要提醒控制器下发table miss(默认流表)
# install the table-miss flow entry.
# 匹配域的作用是过滤需要接收的数据,这里不传入任何参数表示所有数据都接收
match = ofp_parser.OFPMatch()# 匹配域
# 指定交换机要执行的操作
# 发送操作,第一个参数指定发送到哪个入端口,表示控制器,第二个参数表示需不需要缓存,
# 因为交换机一收到消息就通知控制器下发流表,所以设置不需要缓存
actions = [ofp_parser.OFPActionOutput(ofproto.OFPP_CONTROLLER,
ofproto.OFPCML_NO_BUFFER)]
# self 调用对象自己的函数
self.add_flow(datapath,0,match,actions)
# 写自己的函数来提高存活率
def add_flow(self,datapath,priority,match,actions):
# add a flow entry and install it into datapath
ofproto = datapath.ofproto
ofp_parser = datapath.ofproto_parser
#contruct a flow_mod msg and sent it
# 设置指令,立马执行操作的指令
inst = [ofp_parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
actions)]
# 将上面的收发数据集合在FlowMod里面
mod = ofp_parser.OFPFlowMod(datapath=datapath,priority=priority,
match=match,instructions=inst)
# 将mod发送出去
datapath.send_msg(mod)
# 数据包进来了我们来处理的操作 package_in_handler
# 利用Ryu控制器中的机制:通过装饰器注册监听事件,从而实现从数据平面的消息上传到控制器,再到应用程序,应用程序处理这个事件,然后逐渐下发,往控制器平面,再通过南向接口,再把消息发到openVSwitch
# 这个注解是装饰器,第一个参数是监听什么事件 OpenFlow Packet In Event,第二个参数是在什么状态下监听 Main 状态
@set_ev_cls(ofp_event.EventOFPPacketIn,MAIN_DISPATCHER)
def package_in_handler(self,ev):
# 从事件中获取必要的参数
msg = ev.msg
datapath = msg.datapath
ofproto = datapath.ofproto
ofp_parser = datapath.ofproto_parser
# 获取匹配端口
in_port = msg.match['in_port']
# contruct a flow entry
# 接收所有数据
match = ofp_parser.OFPMatch()
# 指定发送操作为泛洪
actions = [ofp_parser.OFPActionOutput(ofproto.OFPP_FLOOD)]
# install flow_mod to avoid packet_in next time
self.add_flow(datapath,1,match,actions)
# 数据发送出去
out = ofp_parser.OFPPacketOut(
datapath=datapath,buffer_id=msg.buffer_id,in_port=in_port,
actions=actions)
datapath.send_msg(out)
Hub/集线器的验证
-创建实验环境,验证解决方案
- /ryu/ryu/app$ ryu-manager hub.py --verbose
- 如果有错找自己写的部分
- 成功
- 创建一个新的终端
- sudo mn --controller remote
- pingall