1.4 OpenFlow消息
控制器和交换机之间的通信采用OpenFlow协议,通过安全信道在实体之间传递一组预定义的消息,安全信道是将每个交换机连接到控制器的接口。交换机开机启动后,便会向用户定义的控制器(或者固定的控制器)发起传输层安全(Transport Layer Security,TLS)连接,控制器的默认TCP端口是6633。交换机和控制器相互交换证书进行认证,证书用特定站点的私钥签名,用户必须能够对每个交换机进行配置,用其中的一个证书对控制器进行认证(控制器证书),用另一个证书向控制器提供交换机认证(交换机证书)。
通过安全信道传输的双向流量不用跟流表进行比对,所以,交换机在进行查表比对之前,必须把输入的流量视为本地流量。当发生交换机和控制器联系中断的情况时,通常是由echo请求超时、TLS会话超时,或者其他连接中断引起,交换机需要尝试去连接一个或者多个后备控制器。如果若干次(0次或多次)连接控制器的尝试失败,交换机必须进入紧急模式,并重置当前的TCP连接。这时,匹配过程由紧急流表记录(其emergency标志位值为1)来控制,紧急流修改消息必须将超时值设为0,否则交换机就必须拒绝更多的流并且以错误信息响应。进入紧急模式后,所有的正常记录都会被删除。与控制器重新建立连接后,紧急流记录依然保留,控制器可以根据需要选择是否将所有流记录删除。
交换机第一次引导启动时,可以认为是处于紧急模式。对于如何配置默认流记录的问题,OpenFlow协议中没有进行规定。
控制器通过安全信道这个接口对交换机进行配置和管理,接收来自交换机的事件报告,并向交换机发送数据包。利用OpenFlow协议,远程控制器能够添加、更新、删除交换机流表中的记录。这些操作既可以被动发生(用以对某个所接收的数据包做出响应),也可以主动发生。可以把OpenFlow协议视为控制器和交换机之间交互的一种可能的实现方案(南向接口),因为它定义了交换硬件和网络控制器之间的通信。出于安全的考虑,OpenFlow 1.3.x提供了可选的对加密TLS通信的支持,以及交换机和控制器之间的证书交换机制,不过目前尚未给出具体的实现方案,也没有对证书格式做出规定。此外,对于如何只给一个授权控制器赋予有限的访问许可,当前规范中也没有给出具体的方法,因此,有关多控制器应用场景的更细粒度的安全选项也未在当前规范中涉及。
OpenFlow协议定义了以下三种消息类型,每种又可分为若干种子类型。
控制器到交换机的消息。
对称的消息。
异步的消息。
1.4.1 控制器到交换机的消息
控制器到交换机的消息由控制器发起,用于直接管理交换机或查看交换机的状态。这类消息既可以要求交换机响应,也可以不要求响应。这类消息可以细分为如下的子类型。
Features消息
TLS会话一经建立,控制器便向交换机发送feature请求消息,交换机必须用feature应答消息进行回复,并在其中详细说明交换机所支持的特性和功能。
Configuration消息
控制器可以设置和查询交换机中的配置参数,而交换机只对控制器所发出的查询消息做出响应。
Modify-State消息
这类消息由控制器发出,用于管理交换机的状态,通过这类消息添加、删除或者修改流表中的流记录,或者设置交换机端口的优先级。流表修改消息可以采用以下的类型:
ADD:对于设置了OFPFF_CHECK_OVERLAP标志的ADD请求,交换机必须首先检查有没有重叠(overlapping)的流记录。如果一个数据包同时与两个流记录匹配,且两者具有相同的优先级,则这两个流记录就是重叠的。如果ADD请求与现有的流记录之间存在重叠冲突,交换机必须拒绝这个添加操作请求,并用ofp_error_msg作为响应,设置其错误类型为OFPET _FLOW_MODE_FAILED,错误代码为OFPFMFC_OVERLAP。对于有效的ADD请求(没有重叠),或者没有设置重叠检查标志位的ADD请求,交换机必须将流记录插入到流表中最低编号的记录处,对于该记录,交换机支持其flow_match结构中的所有通配符集合,并在查找匹配的过程中查看其优先级,如果流表中已经存在了一个具有相同的首部字段和优先级的流记录,则必须将这个流记录连同其计数器删除,再把新的记录加进来。如果交换机在表中找不到添加所输入流记录的位置,则需要发送ofp_error_msg,设置其错误类型为OFPET _FLOW_MODE_FAILED,错误代码为OFPFMFC _ALL_TABLES_FULL。如果在流修改消息的操作列表中引用了一个交换机的无效端口,则交换机必须返回ofp_error_msg响应,设置错误类型为OFPET _BAD_ACTION,错误代码为OFPBAC_BAD_OUT。如果所引用的端口以后有可能会生效(例如,在交换机的某个插槽中插入了一块线路接口卡),则交换机可以选择简单地丢弃发送到这个端口的数据包,不产生错误信息;或者返回一个OFPBAC_BAD_PORT错误,并拒绝这个流修改消息。
MODIFY:如果当前流表中不存在具有相同首部字段的流记录,则MODIFY命令的功能就和ADD命令一样,新的流记录插入时其计数器值必须设置为0。如果当前流表中存在相同的首部字段的流记录,就修改现有流记录中的操作字段值,而计数器值和空闲超时字段的值保持不变。
DELETE:对于删除请求,若表中没有匹配的流记录,则不产生任何错误信息,流表也不发生任何改动。如果有匹配的流记录,则必须删除该记录,设置了OFPFF_SEND_FLOW_REM标志的普通流记录将产生一条流清除(removal)消息。删除紧急流记录不会产生流清除消息。输出端口可以选择过滤DELETE和DELETE_STRICT命令。如果out_port字段包含的值不是OFPP_NONE,则查找匹配时引入一个约束条件,这个约束条件就是:规则中必须包含一个导向这个端口的输出操作。而ADD、MODIFY和MODIFY_SRTICT消息则会忽略这个字段。
MODIFY和DELETE:这两个流模式命令都有相应的_STRICT版本,在非_STRICT版本中,通配符是起作用的,所有跟描述符相匹配的流都会被修改或删除。而在_STRICT版本的命令中,包括通配符和优先级在内的所有字段必须跟流记录严格匹配,只有完全相同的流才会被修改或删除。譬如,如果给交换机发送了一条删除记录的消息,在其中设置了所有的通配符标志,则DELETE命令将会从所有的流表中删除所有的流记录;而DELETE_STRICT命令则只删除适用于指定优先级上所有数据包的那条规则。对于非_STRICT的包含通配符的MODIFY和 DELETE命令,只有当与流记录精确匹配,或者比flow_mod更精确时,才被作为一个匹配看待。例如,如果一条DELETE命令要求删除所有目的端口为80的流,那么,一条包含了所有通配符的流记录将不会被删除;然而,一条包含了所有通配符的DELETE命令,将会删除一条匹配所有80端口流量的流记录。
Read-State消息
这类消息从交换机的流表、端口和单条流记录中收集统计数据。
Send-Packet消息
控制器利用这类消息从交换机的指定端口发送数据包。
Barrier消息
控制器使用Barrier请求和应答消息来确保消息的相互依存性或者接收操作完成的通知。
1.4.2 对称消息
对称消息既可以由交换机主动发送,也可以由控制器主动发送,根据OpenFlow协议的定义,对称消息有以下三种类型。
Hello消息
交换机和控制器建立连接之后,交换Hello消息。
echo消息
echo请求消息既可以由交换机发出,也可以由控制器发出,另一方必须反馈echo应答消息。echo消息用于传送延时和带宽信息,以及控制器与交换机之间连接的保活(即心跳)信息。
Vendor消息
Vendor类消息旨在利用OpenFlow消息类型空间,为OpenFlow交换机的功能扩展提供一种标准化的途径,便于将来OpenFlow协议的修订更新。
1.4.3 异步消息
异步消息由交换机发起,用来向控制器通告网络事件和交换机状态的变化。交换机发送异步消息以告知数据包的到达、交换机状态的改变,或者出现了错误。异步消息主要分为以下四种。
packet-in消息
对于所有没有找到相匹配的流记录的数据包,或者匹配记录所规定的操作是“发送到控制器”,交换机都会向控制器发送一个packet-in消息。如果交换机有充足的缓存空间来存储要发给控制器的数据包,packet-in消息中会包含部分数据包首部(默认为128字节)和缓存区的ID,当交换机做好准备转发该数据包时,这些信息就可以供控制器使用。如果交换机不支持内部缓存,或者内部缓存区空间耗尽了,就必须把包含全部数据包的packet-in消息发送给控制器。
flow-removal消息
当通过流修改消息向交换机添加一条流记录时(见1.4.1节),空闲超时计数器的值可以反映出何时可以把不活跃的流记录清除,也可以根据硬超时值决定何时清除一条流记录,硬超时值则与流记录的活跃与否无关。当一个流过期时,流修改消息还能够规定交换机是否应该向控制器发送一条流清除消息。用来进行删除(delete)操作的流修改(modify)消息,也会产生流清除(flow removal)消息。
port-status消息
当交换机的端口配置状态改变时,应该向控制器发送端口状态(port-status)消息,这些事件包括端口状态的改变(例如端口被用户禁用),或者根据802.1D(支撑树)所定义的端口状态改变。OpenFlow可以把支撑树协议(Spanning Tree Protocol,STP)作为可选项来支持,这些交换机在进行查表操作之前,应该先在本地处理所有的802.1D数据包,由STP定义的端口状态则被用来对数据包的转发进行约束,只能转发给那些沿着支撑树分布的端口,限制其到OFP_FLOOD端口的转发。由支撑树协议所带来的端口变化将通过端口更新消息发送给控制器。需要注意的是,规定向输出端口OFP_ALL的转发操作将忽略STP设置的端口状态,从STP所禁止的端口上接收的数据包必须按照正常的流表处理途径转发。
error消息
交换机用error消息来向控制器通报错误。
OpenFlow规范的核心是一组供OpenFlow协议使用的C语言结构体,对此感