代码结构

Ryu控制器运行性能无法与以C++实现的SDN控制器(如NOX)相比
全局解释器锁( Global Interpreter Lock, GIL)的存在导致其无法充分利用多核CPU
但Python简单易学、能够快速上手,拥有诸多动态语言的高级特性以及丰富的开源类库
Ryu控制器的整体架构清晰明了,而且控制器本身也自带很多编写好的APP

Ryu的源码结构如图所示
image.png

  • cmd目录下的代码是Ryu框架的入口程序,它会调用Ryu核心组件的初始化程序
  • base目录下进行组件的初始化,同时base目录还包含了Ryu组件中基类RyuApp的定义
  • app目录下包括GRE Tunnel、REST API等组件
  • topology目录是有关拓扑的组件
  • controller目录中控制器也作为一个组件
  • ofproto目录下OpenFlow的协议解析模块
  • services目录下是一些基于Ryu框架开发的应用服务
    • 目前有VRRP(虚拟路由器冗余协议)
    • BGP(边界网关协议)
    • OVSDB(开放虚拟交换机数据库)
    • Zebra(TCP/IP路由协议守护进程的API)
  • contrib目录下则是第三方贡献的代码
  • tests 目录下是测试代码
  • lib目录下是一些基本的网络相关的库

    • 提供了一些有用的库以便开发者能够更轻松地开发出自己的网络应用程序
    • 比如用来帮助解析和生成不同协议的数据分组的Packet库
    • 用于提供与OVSDB交互的功能OVS库
    • 与NETCONF定义相关的NETCONF库等

      代码解析

  • Ryu是基于组件的框架,这些组件都以Python模块的形式存在

  • 模块中包含一个RyuApp类的子类,组件中可以定义针对特定事件进行处理的函数。
  • 目前Ryu中包含的组件类型及功能可基本分为:

    • 基础核心组件( Base包组件、Controller包组件)
      • 基础核心组件提供组件加载、底层通信以及事件派发等基础核心功能
    • 协议类组件
      • 协议组件主要定义不同协议消息格式、版本参数等
    • 基础应用组件
      • 基础应用组件提供诸如交换机转发策略、隧道策略等基础应用
    • REST应用组件
      • REST应用组件提供REST服务访问功能

        Base组件包

  • 该组件包只包含模块管理器(app_ manager) 单个组件,它是Ryu应用组件的管理中枢

  • 具有加载Ryu应用组件、为组件提供上下文(Context)及传递组件间消息的作用
  • app_manager中定义的RyuApp类是Ryu应用组件的基础类
  • Ryu应用组件需要定义继承该类的子类

  • 该组件的主要流程是组件加载流程,如图所示

image.png

  • app_manager 从模块列表中读取组件模块并导入
  • 然后获取组件模块中的RyuApp派生类
  • 再获取该派生类上下文类并缓存到上下文字典中
  • 如果上下文字典中存在RyuApp派生类且依赖其他服务类,则将此依赖服务类加入到组件列表中等待解析加载
  • 如果该模块中的RyuApp派生类本身也依赖其他服务类且该服务类不存在于上下文字典中,则同样将其加入到组件列表。
  • 待组件列表解析完成后将上下文字典中RyuApp派生类实例化注册并缓存,再进一步实例化应用字典类
  • 最后启动RyuApp派生类应用

    Controller组件包

  • Controller组件包主要包括Controller、ofp_handler、ofp_event 等组件。

  • Controller是Ryu控制器的主要组件,管理与OpenFlow交换机连接的安全通道
  • 接收、发送OpenFlow消息,发布事件以及触发订阅组件处理
    • ofp_handler负责管理控制器、交换机间握手、协商过程的处理
    • ofp_event则主要负贵完成OpenFlow消息一事件的转化
  • Controller组件主要由OpenFlowContoller 和Datapath两类构成
  • OpenFlowContoller负责监听与Ryu连接的OpenFlow网络中的事件,一旦有事件发生,会创建一个Datapath对象负责接收来自该事件的连接和数据,并将这些事件的数据分组进行解析,封装成Ryu的事件对象,然后派发给对这些事件感兴趣的组件。
  • Controller 与ofp_handler 和ofp_event协同运作完成连接管理、事件收发等一系列功能,它们之间的数据交互及事件派发处理流程如图所示。

image.png

  • 从图中可以看出
  • of_handler组件被加载启动后会触发Controller创建监听服务
  • 当监听到交换机连接后启动针对该连接的接收和发送进程
  • 接收进程读取数据分组后构建相应事件,而后通知观察者和订阅组件处理该事件,如此周而复始
  • 发送进程获取发送队列中待发送消息,通过Socket发往交换机
  • 该过程同样不断重复,直到系统停止运行时结束

    ofproto组件包

  • ofproto组件包定义了与OF协议相关的组件,主要用于协议消息的封装/解析

    • ofprotolx.py (x=0,1,2,3,4,5) 定义了相应协议版本的参数
    • ofprotol1x parser.py (x=0,1,2,3,4,5) 定义了相关协议版本消息的封装格式

      APP组件包

  • APP组件包主要存放Ryu控制器的应用组件,包括基础应用组件和REST应用组件。

    • REST应用组件主要提供REST服务
    • 基础应用组件主要包括simple_switch、simple_switch_igmp、simple_switch_lacp、 simple_switch_snort、simple_switch_stp等。
  • simple_switch 组件实现了传统的二层交换机策略

  • simple_switch_igmp 实现了互联网组管理协议窥探策略
  • simple_switch_stp 实现了使用无广播环路(使用STP)的二层交换机策略
  • simple_switch_lacp 实现了链路汇聚控制协议策略

  • APP 组件包组件较多,这里仅选取simple_switch 具有代表性的组件做进一步解析。

  • 详细代码内容见

【Ryu】二层交换应用

  • simple_switch组件实现了传统的二层交换机策略
  • 该组件的核心处理流程是对Packet-in消息处理,其处理流程如图所示

image.png

  • 首先,从上报事件中获取消息( msg )、Datapath、ofproto
  • 然后从消息中获取以太类型、源、目的地址等信息
  • 接着获取端口网络标识(in_ port), 添加源MAC地址和端口映射关系
  • 如果目的地址已经在映射关系中,则取出端口,否则出端口为洪泛端口
  • 设置流表的actionsns,然后安装流表,发送Packet-out报文,整个流程到此结束