0x00 目录

0x01 前言

本文主要参考OpenFlow v1.5.1协议、v1.3.0协议以及SDN相关书籍,对OpenFlow中主要机制(如流表与流水线处理、组表、计量表等)的原理进行解析

0x02 OpenFlow简介

OpenFlow由斯坦福大学Nick Mckeown教授提出,为SDN控制平面与数据平面之间提供通信接口标准,以实现SDN网络的转控分离架构。OpenFlow协议允许SDN控制器直接访问和操作数据平面中的网络设备,控制网络转发行为,数据平面采用基于流的方式进行转发。目前由ONF(Open Networking Foundation)负责推广和制定OpenFlow标准,截至本文发表时,最新版本为1.5.1

OpenFlow版本变迁

0x03 SDN与OpenFlow的关系

可以说OpenFlow是SDN中非常重要的技术,以至于许多人(包括笔者在内)在谈及SDN时就自然联想到OpenFlow。但SDN与OpenFlow不是划等号的关系,而是SDN包含OpenFlow的关系。实际上,SDN有多种实现方案,在ONF SDN方案中OpenFlow充当南向接口的作用。
南向接口的定义是控制平面与数据平面之间进行交互的协议,南向接口除了可以采用OpenFlow外,还有许多别的协议,如OF-CONFIG、OVSDB、NETCONF、PCEP、XMPP等等

0x04 基于OpenFlow的SDN网络工作原理

传统网络中网络设备的工作过程

假设主机A向主机B发送IP数据包,且所有路由表和MAC地址表中都有该数据包的相应表项

  • 路由器之间运行分布式路由协议构建路由表。查表成功则基于目的IP地址转发;查表失败时,丢弃数据包
  • 交换机根据自学习算法构建MAC地址表。查表成功则基于目的MAC地址转发;查表失败时,除入端口外其余所有端口转发出去

传统网络中网络设备的工作过程

基于OpenFlow的SDN网络中网络设备的工作过程

假设主机A向主机B发送IP数据包,且所有流表有该数据包相应表项

  • OpenFlow交换机查询流表来转发数据包,查表成功则基于匹配域(如目的IP地址+源IP地址)转发;查表失败时,则询问SDN控制器
  • 流表由SDN控制器来构建

流表不空时,基于OpenFlow的SDN网络中网络设备的工作过程

假设主机A向主机B发送IP数据包,且OpenFlow交换机中流表为空

  1. OF交换机接收IP数据包
  2. OF交换机解析数据包首部并查询流表,由于流表为空,不知道如何转发,因此需要询问控制器
  3. OF交换机向控制器发送Packet-In消息
  4. 控制器为主机A发送给主机B的IP数据包计算路由
  5. 控制器向OF交换机下发流表,使用FlowMod消息承载流表信息,OF交换机接收该消息后安装流表
  6. 控制器向OF交换机发送Packet-Out消息,指示OF交换机按照刚安装好的流表转发IP数据包
  7. OF交换机收到Packet-Out消息后转发数据包
    流表为空时,基于OpenFlow的SDN网络中网络设备的工作过程

小结

  • 路由计算、转发规则(流表)下发由控制器完成
  • OF交换机只需要按照流表进行转发,查表失败时,通过Pacekt-In消息询问控制器

传统网络与OpenFlow网络中网络设备对比

0x05 流表与流水线处理

在介绍流表之前,需要先解释流的概念,流(Flow)就是具有相同特征的数据包集合。例如,源MAC地址为MAC_A,目的MAC地址为MAC_B的所有数据包集合就可以视为一条流,可见流具有方向性。有别于传统网络中路由器基于数据包独立转发的模式,使用OpenFlow的SDN网络是基于流进行转发的,即对相同特征的数据包集合采用同样的处理。

流表

流表(Flow Table)是OpenFlow中最重要的一张表,它用于指导OpenFlow交换机对收到的数据包进行转发,相当于二层的MAC地址表和三层的路由表。在OpenFlow 1.1以后的版本中,每台交换机支持使用多张流表,构成流水线处理,从而完成对数据包更为复杂的处理。

流表由若干条流表项(Flow Entry)组成,流表项结构如下图所示。

流表项结构

  • 匹配域(Match Fields):用于定义某条流,也是流表匹配的依据
  • 指令(Instructions):表示对该条流应该如何处理
  • 优先级(Priority):表示该流表项的优先匹配程度
  • 计数器(Counters):用于统计该条流的信息
  • 生存时间(Timeouts):表示流表项的有效存活时间
  • Cookie:控制器设置用来过滤被流统计、流修改和流删除操作请求影响的流表项
  • 标志(Flags):用于流表项管理

流表项最为重要的两项为匹配域和指令,当OpenFlow交换机收到一个数据包,将它包头解析后与流表中流表项匹配域进行匹配,匹配成功则执行指令,因此流表可以简化理解为key-value形式的{匹配域-指令}表。

匹配域

OpenFlow提供丰富的匹配域字段来定义不同粒度的流,如可以基于目的IP地址定义一条流,也可以根据源IP地址 + 目的IP地址来定义一条流
匹配域

指令与动作

指令(Instruction)是流表项匹配成功时的处理动作,分为三类

  • 更新动作集(Action Set):添加、修改、清空动作集,前面两个对应Write-Actions指令,清空动作集对应Clear-Actions指令
  • 修改流水线处理次序:从序号低的表跳转到序号高的表,对应Go-To-Table指令
  • 其他:更新元数据以及设定触发器,分别对应Write-Metadata指令和Stat-Trigger指令

指令

动作(Action)
Action是指对数据包的具体处理动作,可分为两类,一类是定义数据包的转发,另一类是修改数据包包头字段

动作

流表匹配过程

解析数据包得到的首部字段,用于与流表项匹配域进行匹配。若一个数据包与多个流表项匹配成功,最后只与优先级最高的流表项进行匹配。

  • 匹配成功,更新计数器,执行相应指令
  • 匹配失败
    • 流表中没有设置Table-Miss流表项,匹配失败时,丢弃数据包
    • 流表中设置有Table-Miss流表项(优先级为0且匹配域为ANY),则最后会匹配该表项,执行相应指令(如丢弃、交由控制器处理、交给下一张流表处理)

流表匹配过程

例子——使用单流表转发数据包

假设主机A发送数据包给主机B,使用单张流表的OF交换机处理数据包过程,如图所示

  1. OF交换机从1端口接收数据包
  2. OF交换机解析数据包首部,并查询流表进行流表匹配,匹配第一条流表项,并执行相应指令
  3. 将数据包转发到OF交换机的2端口

使用单流表转发数据包

多级流表与流水线处理

从OpenFlow1.1开始引入了多级流表和流水线处理机制,多级流表的出现一方面能够实现对数据包的复杂处理,另一方面又能有效降低单张流表的长度,提高查表效率。每张表都有序号,数据包通过跳转指令按照流表序号递增的方向在多个流表之间进行匹配,这样就构成了一条流水线,如下图所示,可见流水线处理是有方向的。流水线处理可以在OpenFlow交换机的入端口或出端口上进行,一般都在入端口出进行流水线处理。当流水线上只有一张流表时,就简化成单流表匹配的情况。

流水线处理机制

  • 流水线处理开始:OpenFlow交换机接收数据包后,执行入端口的流水线处理,同时给该流水线分配一个动作集(Action Set)
  • 流表匹配
    • 匹配成功
      • 更新相应流表项的计数器,完成对该条流的统计工作
      • 执行流表项对应的指令
    • 匹配失败:一个数据包可能在流表中与所有的流表项都不匹配或者匹配到Table-Miss流表项(优先级为0且匹配域为ANY),这两种情况都称为Table-Miss,对于前者,OpenFlow交换机将丢弃数据包;对于后者,OpenFlow交换机根据Table-Miss流表项,处理数据包(丢弃数据包、转发给控制器、交给下一个流表处理)
  • 流水线处理结束:若当前不是执行跳转指令,则执行动作集中的所有动作,完成对数据包的处理,然后结束流水线处理

例子——多级流表实现对流的细粒度控制

使用多级流表实现主机A发送到给主机B的所有TCP报文正常转发,UDP报文均丢弃,从而实现对不同流的细粒度控制
基本思想:

  1. 流表0中匹配主机A到主机B的IP流,然后跳转到其他流表,如流表2
  2. 流表2中在IP流的基础上进一步匹配TCP流或UDP流,根据要求将TCP流正常转发,UDP流丢弃

多级流表实现对流的细粒度控制

0x06 OpenFlow的两种下发流表方式

根据流表的安装时机,可分为Proactive方式和Reactive方式

Proactive

在数据包还未到达OpenFlow交换机前,SDN控制器就向OpenFlow交换机主动下发流表,这种方式相当于预置路由

例如Table-Miss表项,就需要采用Proactive方式在SDN控制器与OpenFlow交换机建立连接后下发,显示的指定数据包查表失败时,OpenFlow交换机的处理方式

Reactive

数据包到达OpenFlow交换机因查流表失败时,产生Packet-In消息询问SDN控制器,SDN控制器计算路由后下发流表到OpenFlow交换机,这种方式相当于按需下发路由,只有在有路由需求且查流表失败时,才会触发新的流表安装

0x07 组表

独立于流水线之外,每台OpenFlow交换机只有一张组表。组表(Group Table)由若干条组表项(Group Entry)组成,具有将多个端口定义为一个组的能力,从而实现广播、多播,负载均衡、链路聚合、故障转移等

组表项结构如图所示,定义了一到多个动作桶(Action Bucket),用于描述转发到指定端口前,对数据包的处理。

组表项结构

组类型

例子——使用组表实现多播

假设主机A使用多播方式向主机B和C发送IP数据包
使用组表实现多播

0x08 计量表

对流进行测量,从而为流提供QoS功能,如限速、DiffServ

每台OpenFlow交换机只有一张计量表(Meter Table),由若干计量表项(Meter Entry)组成,每个计量表项可以定义一至多个计量带(Meter Band),计量带定义了带宽阈值和数据包处理方式(丢弃、DSCP标记)

计量表

例子——对流进行限速

假设对某条流X(目的IP地址:10.0.0.2)进行限速,且当前测得流X数据包的速率为1200kBps

  • 流表匹配后,交由计量1处理
  • 由于测得数据包速率1200kBps > 带宽阈值1000,根据计量带0定义的处理方式丢弃数据包,从而实现限速
    注:带宽阈值本身是无单位的数值,其表示含义取决于应用场景
    对流进行限速

0x09 OpenFlow消息

种类

消息按照发送的位置可分为三大类,每一大类中有若干子消息

  • Controller-to-Switch消息:SDN控制器主动发送给OpenFlow交换机的消息

    • Features:用于获取交换机特性
    • Configuration:用来配置和查询交换机参数
    • Modify-State:用来修改交换机状态信息(增删改流表项、组表项等)
      • Table-Mod消息
      • Flow-Mod消息(流表操作,添加、删除、修改流表项)
      • Group-Mod消息
      • Port-Mod消息
      • Meter-Mod消息
    • Read-State:用来读取交换机状态信息(当前配置、统计信息等)
      • Port-Stats消息
      • Flow-Stats消息
    • Packet-Out:用来指定交换机将数据包从指定端口转发出去
    • Barrier:在不同消息之间使用,确保操作顺序执行
    • Role Request:控制器用于询问或设置自身在交换机中的角色,常用于交换机与多控制器连接的场景
    • Asynchronous-Configuration:控制器设置异步消息过滤器,只接收感兴趣的异步消息,一般在多控制器场景下使用
  • Asynchronous(异步)消息:OpenFlow交换机主动发送给SDN控制器的异步消息

    • Packet-In:将数据包交给控制器处理,一般流表匹配中出现Table-Miss时或流表项显示指定将数据包交给控制器时,触发该消息
    • Flow-Removed:通知控制器,流表项被删除;流表项超时或控制器删除流表项时触发该消息(需要在交换机配置时使能该消息)
    • Port-status :通知控制器,交换机端口状态发生变化
    • Role-status:通知控制器,控制器在交换机中的角色发送变化
    • Controller-Status:通知控制器,OpenFlow通道状态发生变化
    • Flow-monitor:通知控制器,流表发送变化
  • Symmetric(对称)消息:可由SDN控制器或OpenFlow交换机主动发送的消息
    • Hello:建立控制器与交换机之间的OpenFlow通道
    • Echo:检测交换机与控制器之间的连接状态或测量OpenFlow通道的时延和带宽
    • Error:用于通告错误
    • Experiment:用于实验,测试新特性

OpenFlow消息种类

Flow-Mod消息

Flow-Mod消息用于流表操作,包括添加、删除、修改流表项。该消息由控制器下发给交换机,从而指导交换机对数据包的处理。

其在OpenFlow1.3中的消息格式如下图所示。
OpenFlow1.3中Flow-Mod消息格式

  • command:
    • ADD:添加流表项
    • MODIFY:根据匹配域,修改所有匹配的流表项,可能有多条流表项被修改
    • MODIFY_STRICT:根据匹配域以及优先级,修改特定的流表项,只有一条流表项被修改
    • DELETE:根据匹配域,删除所有匹配的流表项,可能有多条流表项被删除
    • DELETE_STRICT:根据匹配域以及优先级,删除特定的流表项,只有一条流表项被删除
    • 参考「OpenFlow」流表项删除DELETE与DELETE_STRICT的区别

Packet-In消息

Packet-In消息用于将OpenFlow交换机上指定数据包交给控制器处理,一般流表匹配中出现Table-Miss时或流表项显示指定将数据包交给控制器时,触发该消息。此外,它还能用于主动测量时回收探测包,从而结合Packet-Out消息实现对网络拓扑与链路时延的测量,详情参考基于OpenFlow消息的网络测量方法

其在OpenFlow1.3中的消息格式如下图所示。
OpenFlow1.3中Packet-In消息格式

  • buffer_id:若该字段为-1,表明交换机未缓存数据包,Packet-In消息需要携带完整数据包发送至控制器;否则,表明数据包已在交换机上缓存,Packet-In消息只携带部分数据包上传至控制器。

Packet-Out消息

Packet-Out消息用于指定交换机将数据包从指定端口转发出去。触发该消息的情况有两种:1.转发Packet-In消息携带的数据包 2.转发控制器主动构造的数据包(如用于链路发现的LLDP报文)。此外,由于该消息能够携带自定义数据包,控制器通过在Packet-Out消息中封装探测包并下发至指定交换机,就能够发起主动测量任务,配合Packet-In消息可实现对网络拓扑与链路时延的测量,详情参考基于OpenFlow消息的网络测量方法

其在OpenFlow1.3中的消息格式如下图所示。
OpenFlow1.3中Packet-Out消息格式

  • buffer_id:若该字段为-1,表明交换机未缓存数据包,Packet-Out消息携带控制器创建的数据包发送至交换机;否则,Packet-Out消息表示交换机需要将本地缓存的数据包按照Packet-Out中的actions进行处理。

Port-Stats消息

Port-Stats消息是统计消息(以Stats结尾的消息)的一种,用于控制器查询交换机的端口计数器,从而获取端口的统计信息(如端口接收/发送字节数、接收/发送数据包个数等)。此外,它还能用来测量丢包率和吞吐量,详情参考基于OpenFlow消息的网络测量方法

该消息具体有两种,一种是Port-Stats-Request消息,用于SDN控制器请求交换机端口统计信息,另一种是Port-Stats-Reply消息,交换机用它来应答SDN控制器,它们在OpenFlow1.3版本中的消息格式如下图所示。

OpenFlow1.3中Port-Stats-Request消息格式

OpenFlow1.3中Port-Stats-Reply消息格式

0x0A 参考



SDN     

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!