open flow总结
OpenFlow的设计目标之一就是将网络设备的控制功能与转发功能进行分离,进而将控制功能全部集中到远程的控制器上完成,而OpenFlow交换机只负责在本地做简单高速的数据转发。在OpenFlow交换机的运行过程中,其数据转发的依据就是流表。
在交换机中的每个流表中包含的一组流表项,用来匹配数据包,每组流表项就是一个转发规则。进入交换机的数据包通过查询流表来获得转发的目的端口。流表项由头域(匹配字段)、计数器和操作(指令)组成;其中头域是个十元组,是流表项的标识;计数器用来计数流表项的统计数据;操作标明了与该流表项匹配的数据包应该执行的操作。
所谓流表,其实可被视作是OpenFlow对网络设备的数据转发功能的一种抽象。在传统网络设备中,交换机和路由器的数据转发需要依赖设备中保存的二层MAC地址转发表或者三层IP地址路由表,而OpenFlow交换机中使用的流表也是如此,不过在它的表项中整合了网络中各个层次的网络配置信息,从而在进行数据转发时可以使用更丰富的规则。流表中每个表项的结构如图2-3所示。

图2-3 OpenFlow流表项结构
如图2-3所示,OpenFlow流表的每个流表项都由3部分组成:用于数据包匹配的包头域(Header Fields),用于统计匹配数据包个数的计数器(Counters),用于展示匹配的数据包如何处理的动作(Actions)。
包头域:OpenFlow流表的包头域(OpenFlow v1.1之后被称作匹配域),用于对交换机接收到的数据包的包头内容进行匹配。在OpenFlow v1.0中,流表的包头域中包括了12个元组(Tuple),相关内容如图2-4所示。

图2-4 OpenFlow流表项包头域
如图2-4所示,包头域中用于和交换机接收到的数据包进行匹配的元组涵盖了ISO网络模型中第二至第四层的网络配置信息。每一个元组中的数值可以是一个确定的值或者是“ANY”以支持对任意值的匹配。另外,如果交换机能够在IP地址相关元组上支持子网掩码的话,将有助于实现更精确的匹配。
计数器:OpenFlow流表的计数器可以针对交换机中的每张流表、每个数据流、每个设备端口、每个转发队列进行维护,用于统计数据流量的相关信息。例如:针对每张流表,统计当前活动的表项数、数据包查询次数、数据包匹配次数等;针对每个数据流,统计接收到的数据包数、字节数、数据流持续时间等;针对每个设备端口,除统计接收到的数据包数、发送数据包数、接收字节数、发送字节数等指标之外,还可以对各种错误发生的次数进行统计;针对每个队列,统计发送的数据包数和字节数,还有发送时的溢出(Overrun)错误次数等。
动作:OpenFlow流表的动作用于指示交换机在收到匹配的数据包后应该如何对其进行处理。与传统交换机转发表只需要指明数据包的转发出端口不同,OpenFlow交换机因为缺少控制平面的能力,所以对匹配数据包的处理不仅仅是简单的转发操作,而需要用动作来详细说明交换机将要对数据包所做的处理。
OpenFlow交换机的每个流表项可以对应有零至多个动作,如果没有定义转发动作,那么与流表项包头域匹配的数据包将被默认丢弃。统一流表项中的多个动作的执行可以具有优先级,但是在数据包的发送上并不保证其顺序。另外,如果流表项中出现有OpenFlow交换机不支持的参数值,交换机将向控制器返回相应的出错信息。
动作分为必备动作(Required Actions)和可选动作(Optional Actions)两种类型。其中,必备动作是需要由所有的OpenFlow交换机默认支持的,而可选动作则需要由交换机告知控制器它所能支持的动作种类。OpenFlow流表动作的列表如表2-1所示。
表2-1 OpenFlow流表动作列表
| 类型 | 名 称 | 说 明 |
| 必备动作 | 转发(Forward) |
交换机必须支持将数据包转发给设备的物理端口及如下的一个或多个虚拟端口 ALL:转发给所有出端口,但不包括入端口 CONTROLLER:封装数据包并转发给控制器 LOCAL:转发给本地的网络栈 TABLE:对packet_out消息执行流表的动作 IN_PORT:从入端口发出 |
| 丢弃(Drop) | 对没有明确指明处理动作的流表项,交换机将会对与其所匹配的所有数据包进行默认的丢弃处理 | |
| 可选动作 | 转发(Forward) |
交换机可选支持将数据包转发给如下的虚拟端口 NORMAL:利用交换机所能支持的传统转发机制(例如二层的MAC、VLAN信息或者三层的IP信息)处理数据包 FLOOD:遵照最小生成树从设备出端口洪泛发出,但不包括入端口 |
| 排队(Enqueue) | 交换机将数据包转发到某个出端口对应的转发队列中,便于提供QoS支持 | |
| 修改域(Modify-Field) |
交换机修改数据包的包头内容,具体可以包括: — 设置VLAN ID、VLAN优先级,剥离VLAN头 — 修改源MAC地址、目的MAC地址 — 修改源IPv4地址、目的IPv4地址、ToS位 — 修改源TCP/IP端口、目的TCP/IP端口 |
OpenFlow交换机在接收到网络数据包后,对其开展的处理流程如图2-5所示。

图2-5 OpenFlow交换机中的数据包处理流程
如图2-5所示,流程中对802.1d协议的处理是流程中的可选步骤(在OpenFlow v1.1之后已删除)。当OpenFlow交换机接收到一个数据包时,将按照优先级依次匹配其本地保存的流表中的表项,并以发生具有最高优先级的匹配表项作为匹配结果,并根据相应的动作对数据包进行操作。同时,一旦匹配成功,对应的计数器将更新;而如果没能找到匹配的表项,则将数据包转发给控制器。
OpenFlow交换机对数据包头的解析和匹配过程的细节操作如图2-6所示。
如图2-6所示,交换机中每一个表项的匹配首先按照接收到数据包的物理端口对入端口进行匹配,然后按照二层数据包头进行比较。如果以太网类型为0x8100,即数据包是VLAN包,则继续查询VLAN ID和PCP域。如果以太网类型为0x0806,则为ARP包,继续查询源IP地址和目的IP地址。如果以太网类型为0x0800,即为IP包,则继续查询IP包头的相关域。如果IP包是TCP/UDP包,则还需继续查询传输层端口。如果IP包是ICMP包,则继续查询ICMP包中的Type和Code。对于分段数据包的后续包,则将传输层端口设为0后继续查询。

图2-6 OpenFlow交换机中的数据包头解析和匹配流程
Openflow消息的类型可以总体分为三大类:
1. Controller-to-Switch(控制器到交换机的消息,由控制器主动发出)
- Features用来获取交换机特性
- Configuration用来配置OpenFlow交换机
- Modify-State用来修改交换机状态(修改流表)
- Read-Stats用来读取交换机状态
- Send-Packet用来发送数据包
- Barrier阻塞消息
- Packet-in用来告知控制器,交换机接收到数据包
- Flow-Removed用来告知控制器交换机流表被删除
- Port-Status用来告知控制器交换机端口状态更新
- Error用来告知控制器交换机发生错误
- Hello用来建立OpenFlow连接
- Echo用来确认交换机与控制器之间的连接状态
- Vendor厂商自定义消息
- 目的:协议协商。
- 内容:本方支持的最高版本的协议
- 成果:使用双方都支持的最低版本协议。
- 成功:建立连接
- 失败:OFPT_ERROR (TYPE:OFPT_HELLO_FAILED,CODE =0),终止连接。
端口及端口属性等等。控制器向交换机发送Features Request消息查询交换机特性,Features Request消息只包含Openflow Header。交换机在收到Features Request消息后返回Features Reply消息,Features Reply消息包括Openflow Header 和Features Reply Message;
- 发送时间:连接建立完成之后
- 发送数据:OFPT_FEATURES_REQUEST
- 对称数据:OFPT_FEATURES_REPLY
- 目的:获取交换机的信息
- datapath_id为交换机独一无二的ID号
- n_buffers为交换机可以同时缓存的最大数据包个数
- n_tables为交换机的流表数量
- Capabilities表示交换机支持的特殊功能
- Actions表示交换机支持的动作(见ofp_action_type)
- ofp_phy_ports为交换机的物理端口描述列表,具体结构如下图
- port_no为物理端口的编号
- hw_addr为端口的MAC地址
- name为端口的名称
- config为端口的配置
- State为端口状态
- curr, advertised supported,peer为端口物理属性
- OFPR_NO_MATCH:当交换机收到一个数据包后,会查找流表,找出与数据包包头相匹配的条目。如果流表中有匹配条目,则交换机按照流表所指示的action列表处理数据包。如果流表中没有匹配条目,则交换机会将数据包封装在Packet‐in消息中发送给控制器处理。此时数据包会被缓存在交换机中等待处理。
- OFPR_ACTION:交换机流表所指示的action列表中包含转发给控制器的动作(Output=CONTROLLER)。此时数据包不会被缓存在交换机中。
- buffer_id为packet‐in事件所携带的数据包在交换机中的缓存区ID
- total_len为data段的长度
- in_port数据包进入交换机的入接口号
- Reason为packet‐in事件产生的原因
缓存。控制器收到Packet-in消息后,可以发送flow-mod消向交换机写一个流表项。并且将flow-mod消息中的buffer_id字段设置为packet-in消息中的buffer_id值。从而
控制器向交换机写入了一条与数据包相关的流表项,并且指定该数据包按照此流表项的aciton列表处理。
- type:类型
- ength:整个数据包的长度
- xid:数据包的编号
在of1.0中这里的0,1意义跟我们平时接触的如子网掩码等意义相反,如OFPFW_NW_DST_MASK=0则表示全匹配目标IP。如果为63,则表示不匹配IP。为什么拿这个举例?原因就在于,他的长度是6bit,最大是63,需要将数值转变成对应2进制数值才是我们想要的匹配规则,且注意,1是忽略,0是匹配。如果wildcards全0,则表示由match精确指定,即所有12元组都匹配。
当然高兴的是,在1.3的时候,这个逻辑改成了正常的与逻辑。即1为使能匹配,0为默认不匹配。
- idle_timeout:如值为10,则某条流在10秒之内没有被匹配,则删除,可以称之为活跃时间吧。
- hard_timeout:如值为30,则30秒到达的时候,一定删除这条流,即使他还活跃,即被匹配。
- priority是流的优先级的字段,字数越大则优先级越高,存放在号数越小的table中。
- buffer_id是由交换机指定的buffei_id,准确的说是由dpid指定的。如果是手动下发的流,buffer_id应填-1,即0xffff,告诉交换机这个数据包并没有缓存在队列中。
- out_port为删除流表的flow_mod消息提供额外的匹配参数
- command用来指定操作的类型,共有五种类型:ADD、DELETE、DELETE‐STRICT、MODIFY、MODIFY‐STRICT

浙公网安备 33010602011771号