本节书摘来自华章计算机《软件定义网络:基于OpenFlow的SDN》一书中的第2章,第2.节,作者:Siamak Azodolmolky,更多章节内容可以访问云栖社区“华章计算机”公众号查看。
2.1 OpenFlow参考交换机
OpenFlow交换机是基本的转发单元,可以通过OpenFlow协议和接口对它进行访问。这种架构初看起来似乎简化了交换机的硬件,但是诸如OpenFlow一类的基于流的SDN体系结构要求额外的转发表记录、缓存空间和统计计数器,在传统的采用专用IC芯片(ASIC)的交换机中,这些实现起来并不十分容易。在OpenFlow网络中,有两种类型的交换机:混合型的(可启用OpenFlow)和纯粹型的(只支持OpenFlow),混合型的交换机除了传统的操作和协议(二层、三层交换),还支持OpenFlow。纯粹型的OpenFlow交换机不具有传统特性或板级的控制,完全依赖控制器的转发决策。目前市场上的大部分商用交换机都是混合型的。由于OpenFlow交换机通过一个开放接口(基于TCP的TLS会话)进行控制,维持这个连接的可用性和安全性是很重要的。由于定义了OpenFlow交换机和OpenFlow控制器之间的通信,可以把OpenFlow视为基于SDN的控制器和交换接口的一种可能的实现方案(它是消息协议)。
斯坦福大学提出的OpenFlow的参考实现包括:ofdatapath,实现了用户空间的流表;ofprotocol程序,实现了参考交换机的安全信道;dpctl,是一个交换机配置工具。其发布的软件包还包括一些其他软件,如:一个简单的控制器程序controller,可以连接若干个OpenFlow交换机;一个Wireshark解析器,能够对OpenFlow协议进行解码。下图描述了OpenFlow参考交换机、接口、三种消息类型(控制器到交换机的消息、异步消息和对称的消息)及其子类型。这些消息在前面章节做过简单介绍,本章将涉及它们更多的实现细节。控制器到交换机的消息由控制器发起,可以要求交换机响应,也可以不要求交换机响应。
OpenFlow的1.3.0版本提供了可选的TLS加密通信以及OpenFlow控制器和交换机之间的证书交换机制,不过,没有定义其详细的实现及证书格式。此外,涉及多个OpenFlow控制器应用的细粒度的安全选项也没有在现行规范中涉及,给授权OpenFlow控制器赋予有限访问许可的具体方法也没有定义。这里也提请读者注意,本书内容严格遵循OpenFlow规范的1.0.0版本,OpenFlow 1.0.0的参考实现方案可以从网址www.openflow.org/wp/downloads/下载。
图2-1 OpenFlow接口和消息协议
下述消息直接用于对交换机的状态进行管理和检查。
Features消息:一旦建立起TLS会话(例如:在TCP 6633端口上的TLS会话),控制器将向交换机发送OFPT_FEATURES_REQUEST消息,OpenFlow交换机则用OFPT_FEATURES_REPLY消息报告它所支持的功能特性,向控制器汇报的重要特性有:数据路径标识(datapath_id)、数据路径(指OpenFlow交换机)所支持的流表的数目、交换机的功能、支持的操作和端口的定义。其中,数据路径标识字段(datapath_id)唯一地标识一个OpenFlow交换机(即数据路径),这是一个64比特的实体,其中的低48比特用于交换机MAC地址,高16比特由制造商决定。
Configuration消息:控制器分别用OFPT_SET_CONFIG和OFPT_GET_CONFIG_REQUEST消息设置和查询交换机的配置参数,交换机用OFPT_GET_CONFIG_REPLY消息响应查询配置的请求;交换机对设置配置参数的请求不做出应答。
Modify state消息:控制器通过OFPT_FLOW_MOD消息实现流表的修改,控制器使用OFPT_PORT_MOD消息修改物理端口的行为。修改流的命令是ADD、MODIFY、MODIFY_STRICT、DELETE和DELETE_STRICT,这些命令已经在第1章中讲过。端口配置位可以指示一个端口是否被网管关闭、表示处理802.1D支撑树的数据包选项,以及如何处理输入和输出的数据包。控制器可以将OFPPFL_NO_STP设置为0,以在一个端口启用STP,设置为1则禁止在这个端口使用STP。OpenFlow参考实现方案中默认将该比特设为0(启用STP)。
Read State(统计)消息:控制器使用OFPT_STAT_REQUEST消息查询交换机的状态,交换机回复一个或者多个OFPT_STATS_REPLY消息作为响应。所交换的消息中有一个类型(type)字段,该字段定义所交换的信息类型(如:OpenFlow交换机的描述、单个流的统计信息、聚合流的统计信息、流表的统计信息、物理端口统计信息、一个端口的队列统计信息,以及特定的厂商信息),信息类型决定如何解释信息主体内容。
Queue query消息:一个OpenFlow交换机通过简单的队列机制提供有限的服务质量(Quality of Service,QoS)支持。一个端口上可以有一个或者多个队列,用来将流映射到队列,然后根据对该队列的配置(如最低速率控制)来对待映射到特定队列的流。关于队列的配置不在OpenFlow协议中考虑,可以通过如命令行接口或者专门的外部配置协议实现。控制器可以利用队列查询消息查询交换机端口上的队列配置。
Send packet消息:通过利用这个消息(即OFPT_PACKET_OUT),控制器能够从OpenFlow交换机的特定端口发送数据包。
Barrier消息:当控制器需要确认消息依存关系是否满足,或者希望接收到操作完成的通告时,就发送barrier消息,这个消息就是OFPT_BARRIER_REQUEST,它没有正文部分。OpenFlow交换机收到这个消息后,必须结束对所有之前收到的消息的处理,才能执行任何barrier请求之后接收的消息。当前处理完成后,交换机必须发送应答消息OFPT_BARRIER_REPLY,并在消息中携带原始请求交易的ID(xid)。
2.1.1 异步消息
异步消息由交换机发起,用于向控制器通告新的网络事件和交换机状态的变化。交换机通过向控制器发送异步消息,可以通告数据包的到达、流记录的清除、端口状态的变化,或者错误的发生。
当交换机(数据路径)收到数据包时,可以使用OFPT_PACKET_IN消息向控制器发送接收到的数据包。若交换机缓存该数据包,则可以在消息的数据部分包含数据包的若干字节;如果发送数据包是出于执行“send-to-controller”操作的需要,则发送max_len个字节;如果发送数据包是因为找不到相应的流表记录(失配),那么至少要发送miss_send_len个字节。若交换机没有缓存该数据包,则消息的数据部分要包括整个数据包。实现缓存的交换机应该告知缓存的大小和缓存的占用时间。当没有得到控制器对packet_in消息的响应时,OpenFlow交换机必须能够很好地处理这种情况。
若流记录超时,(若控制器要求通告的话)OpenFlow交换机使用OFPT_FLOW_REMOVED消息通知控制器。消息的duration_sec字段和duration_nsec字段表示流在交换机中存在的时间,用毫微秒(nanoseconds)表示整个持续时间的值,其计算方法是:duration_sec×109 + duration_nanosec。要求系统提供毫秒级(millisecond)的精度。空闲超时(idle_timeout)字段直接从创建流表记录的FLOW_MOD中提取。
当在数据路径上添加、修改或者移除物理端口时,应该通过OPFT_PORT_STATUS消息通知控制器。有时,交换机还需要向控制器通告发生的问题,消息中要包括错误类型、错误代码,以及取决于错误类型和错误代码的可变长度的数据。大多数情况下,数据部分中会给出引发该问题的信息。存在六种类型的错误,OFPET_HELLO_FAILED表示Hello协议失败;OFPET_BAD_REQUEST是指消息请求不被理解;OFPET_BAD_ACTION说明操作描述有错;若FLOW_MOD或PORT_MOD请求失败,错误类型分别为OFPET_FLOW_MOD_FAILED和OFPET_PORT_MOD_FAILED;端口队列操作失败属于OFPET_QUEUE_OP_FAILED类型的错误。
2.1.2 对称消息
OpenFlow中的对称消息包括:hello消息(OFPT_HELLO)、echo请求和应答、厂商消息。在包含了用户空间处理和内核模块的OpenFlow参考实现方案中,echo请求和应答是在内核模块中实现的。这种设计提供了更准确的端到端的延迟定时。OFPT_VENDOR消息中的厂商字段是一个32比特的值,用于唯一地标识厂商。若最高位字节是0,则接下来的3字节(24比特)为厂商的IEEE OUI。如果交换机不能解析厂商扩展信息,必须发送一个OFPT_ERROR消息,其错误类型为OFPET_BAD_REQUEST,错误代码为OFPBRC_BAD_VENDOR。