OpenFlow 交换机规范 1.3.0 (二)

原版OpenFlow Switch Specification Version 1.3.0 (Wire Protocol 0x04) June 25, 2012 包含两部分,前一部分是交换机规范,共6个章节,可以简称为“规范”;后一部分是将OpenFlow协议本身作为附件,可以认为是整体第7章,可以简称为“协议”。
本系列作为中文版,基本忠实原文语句和术语,大部分关键词都是中英文对照。将规范和协议再切分为2部分,共4篇完整呈现。

OpenFlow 交换机规范 1.3.0 第一部分 1-5章
https://www.jianshu.com/p/acfeae1771b3
OpenFlow 交换机规范 1.3.0 第二部分 6章
https://www.jianshu.com/p/82e238eb8d14
OpenFlow协议第一部分
https://www.jianshu.com/p/7eb86d164d26
OpenFlow协议第二部分
https://www.jianshu.com/p/9cc08c698106

本文为6章的内容。OpenFlow协议部分会单独用2篇发布,所以本文也不包含。

6 通道 OpenFlow Channel

OpenFlow 通道是每个交换机连接控制器的接口,通过这个接口,控制器配置和管理交换机,接收来自交换机的事件,从交换机发出数据包。
在数据通路datapath和 OpenFlow通道之间,接口是具体实施者,所有 OpenFlow通道消息的格式必须遵循OpenFlow协议。OpenFlow通道通常使用TLS加密,而且也可能直接运行在 TCP上。

6.1 OpenFlow协议概览

OpenFlow协议支持三种消息类型:控制器到交换机(controller-to-switch)、异步(asynchronous)和对称(symmetric),每个都有多个子类型。 控制器到交换机(controller-to-switch)消息由控制器发起,用来直接管理或检查交换机的状态;异步(asynchronous)消息由交换机发起,用于控制器更新网络事件和交换机状态变化;对称消息(symmetric)发起或者是交换机或者控制器,发送不带有征询。下面介绍 OpenFlow 使用的消息类型。

6.1.1 控制器到交换机 Controller-to-Switch

Controller-to-Switch 是由控制器发起,不强求交换机作出响应。
特性 Features: 控制器通过发送一个特性请求(features request)去查询交换机的能力, 交换机必须用一个特性集合响应,这些特性详细说明了其能力。通常在 OpenFlow 通道建立后执行。
配置 Configuration : 控制器可以设置、 查询交换机的配置参数。 交换机响应来自控制器的查询。
修改状态 Modify-State :mmodify-state 消息由控制器发出,用来管理交换机的状态。它们的首要目标是增加、删除、修改 openflow 表中的流表项 / 组表项,以及设置交换机的端口属性。
读状态 Read-state :控制器用 Read-state 消息去采集交换机的各种消息, 例如当前配置、 统计和能力等。
数据包输出 Packet-out : 控制器用这个 Packet-out 发送数据包到交换机的指定端口,并且通过Packet-in 消息转发收到的数据包。 Packet-out 消息必须包括一个完整的数据包或者一个缓存标识(buffer ID)指向数据包存储在交换机中的位置。这个消息必须包含一个动作(actions)列表, 并按指定顺序应用这些动作(actions)。如果动作(actions)列表为空则丢弃(drops)该包。
堡垒 Barrier: 控制器使用 Barrier 请求/ 回复消息确保ensure消息 依赖上下文或者去完成的操作接收通知。
角色请求 Role-Request: 控制器使用 Role-Request 消息,用来设置 openflow 通道角色, 或者查询这个角色。当交换机连接多个控制器时这个消息则非常有用(见 6.3.4 )。
Asynchronous-Configuration :控制器使用 Asynchronous-Configuration 消息来设置一个附加过滤器,滤出想在 openflow 通道中接受的异步消息,或者用来查询这些过滤器。 这个消息在交换机连接多个控制器时非常有用 (见 6.3.4 ),通常在 openflow 通道建立后运行。

6.1.2 Asynchronous

Asynchronous 消息由交换机发出,无需控制器的征询,交换机发送异步消息到控制器,指示数据包到达、交换机状态改变,或错误。四个主要的异步消息描述如下。
Packet-in: 将对包的控制转移给控制器。由于全部数据包使用流表项(flow entry)或者漏表项(table-miss flow entry)转发到CONTROLLER这个保留端口,packet-in 事件全部发送到控制器(见 5.12 )。其他处理过程,例如TTL 检查, 也可能用到 packet-in 事件将数据包发给控制器。

packet-in 事件可以配置为缓冲数据包(buffer packets)。由流表项或者组存储段(group bucket)中的输出行动产生的packet-in ,可以在输出行动中各自分别指定(见 7.2.5 ),其他的 packet-in 可在交换机中配置(见 7.3.2 )。如果这个 packet-in 事件配置为缓冲数据包,并且交换机中有足够的内存去缓冲它们,当交换机准备转发这个数据包时,这个 packet-in 事件包含仅数据包头部的一小部分和一个控制器缓冲ID。不支持内部缓存的交换机,packet-in 事件配置为不缓冲数据包,或内部缓冲耗尽时,将整个包作为事件的一部分发送给控制器。缓冲过的数据包通常被控制器发来的 packet-out 消息进行处理,或者一段时间后自动过期。
如果数据包已缓冲,包含在 packet-in 中的原始包字节数就可以配置,默认 128 字节。由流表项或者组存储段中的输出行动产生的 packet-in ,可以在输出行动中单独指定(见 7.2.5 ),其他的packed-in可在交换机中配置(见 7.3.2 )。

Flow-Removed :通知控制器一个流表项从流表中移除。流表项只有设置了OFPFF_SEND_FLOW_REM 标志,Flow-Removed 消息才会发送。此消息是由于控制器的流删除请求产生,或者交换机流处理超时产生,即某个流有效时间超出范围了。
Port-status :通知控制器某个端口发生变化。交换机需要在端口配置或状态改变时发送port-status 消息给控制器。 包括端口配置的改变等事件, 例如,端口被用户关闭, 端口状态被用户改变,连接断开等。
Error: 交换机用 Error 消息通知控制器出现问题。

6.1.3 对称 Symmetric

对称(Symmetric)消息向各方向发送时无需征询。

Hello: 在连接启动后,在交换机和控制器之间传递Hello 消息。
Echo: 从交换机或者控制器发出Echo请求request/响应reply消息,必须返回一个echo响应reply。它们主要用来验证 controller-switch 连接是否存活,也可能来测量延迟率和带宽。
Experimenter: Experimenter 消息为交换机在其现有消息类型范围内试图增加功能提供了一个标准方式。这是为openflow 将来修订时的一个功能预留。

6.2 消息处理 Message Handing

Openflow 协议提供可靠的消息传递和处理, 但是不自动提供确认acknowledgements或者保证消息的原序处理。这一节描述的 openflow 消息处理行为是由可靠传输的主链接main connection和辅助链接auxiliary connections上完成的,然而在辅助链接使用不可靠传输是不支持的(见6.3.5)。
Message Delivery: 除非 Openflow 通道完全失败,消息是被保证的,控制器不假设交换机的状态(如交换机可能已经进入了“失败独立模式”)。
Message Processing: 交换机必须完全处理从控制器接收的每个消息, 并可能生成一个响应reply。如果交换机不能完全处理来自控制器的消息,那么它必须返回一个error消息。对于packet-out消息,消息被完全处理之后也不能保证包实际上退出了交换机。 由于交换机的堵塞、QoS策略、或者数据包发送到一个阻塞或无效的端口,交换机处理之后数据包可能被丢弃。
此外,交换机须发送所有OpenFlow状态改变时产生的异步消息,例如流删除 flow-removed,端口状态 port-status或者packet-in消息,这样控制器就可以与交换机的实际情况同步。那些基于异步配置Asynchronous
Configuration的消息可能被过滤 (见 6.1.1 )。而且,在引起这些变化之前,可能触发OpenFlow状态改变的条件也可以被过滤掉。例如,数据端口接收的用来发送到控制器的数据包,由于交换机的阻塞congestion或 QoS策略和 非packet-in 消息,可能被丢弃。这些丢失在数据包有明显输出行动到交换机时会发生,也可能在数据包在表项里没有任何匹配,而且表的默认行动是发给控制器。数据包策略目的是控制器使用QoS行动和速率限制进行监管,以防止控制器链接的拒绝服务,此内容超出本规范范围。

控制器可以自由忽略他们接收的消息,但是必须响应echo messages消息来避免交换机连接中断。

Message Ordering: 排序可以通过使用 barrier 消息来保证。
在缺少barrier消息时 ,交换机可以任意重新排序消息,来达到最佳性能。因此,交换机不应该依赖一个特定的处理顺序。特别的是,流表项可能插入到流表中,其顺序不同于交换机接收到的流修改消息(flow mod messages)。
跨越一个barrier的消息就必须不被打乱,只有前面所有的消息都处理后,barrier消息才被处理。具体的说:

  1. barrier消息前面的消息必须先被处理,包括发送任何产生的错误和回复。
  2. barrier必须被处理,而后发送一个响应。
  3. barrier消息后面的消息可继续处理。
    如果从控制器接收到的 2 个消息是相互依赖的(如,一个流修改跟着一个packet-out 到OFPP_TABLE ),那它们必须通过barrier消息来分离。

6.3 Openflow 通道连接

Openflow 通道用来在控制器和交换机之间交换 Openflow 消息。控制器管理多个 Openflow通道,每个通道连接到一个不同的交换机。一个交换机可能有一个通道连到控制器,或者,有多个通道连接到不同的控制器(见 6.3.4 )。
控制器可以通过一个或者多个网络来远程管理交换机。 这种方法是不在当前规范之内的,所使用的可能是一个独立的专用网络,或者由交换机管理的网络(带内控制器连接)。唯一的要求就是应提供 TCP/IP 连接。
Openflow 通道实际上作为一个交换机和控制器之间的单一的网络连接,使用 TLS或 TCP协议(见 6.3.3 )。另外,为了具有并行性,通道可以由多个网络连接组成。交换机通过初始化到控制器的连接来创建一个到控制器的通道(见 6.3.1 )。一些交换机实现时可能允许一个控制器连接到交换机,这种情况下,交换机通常应保证安全的连接,以防止没有授权的连接。

6.3.1 连接设置

交换机必须能够与一个用户可配置 IP 地址(否则是固定的)的控制器建立连接, 连接使用用户指定的一个端口或是默认端口。如果交换机与控制器的 IP 地址进行配置连接,那么交换机启动了一个标准的 TLS或直接TCP连接。Openflow 通道的流量不通过 Openflow 流水线。因此,交换机必须在流表检查之前就必须区分输入流量。
当 Openflow 连 接 初 次 建 立 之 时 , 连 接 的 每 一 方 必 须 立 即 发 送 携 带 版 本 字 段 的OFPT_HELLO消息,版本代表发送者支持的最高的 OpenFlow 协议版本。这个 Hello 消息可能含有一些可选内容来帮助建立连接(见 7.5.1)。一旦接收到消息,接收方须立即计算出使用的协议版本。如果发送和接收的 Hello 消息都包含 OFPHET_VERSIONBITMAP的 hello 元素,并且如果这些位图有一些共同的位设置,那双方协商的协议是最高版本的。否则,协商版本是接收到的版本字段中较小版本数字。
如果接收方支持协商版本, 那么连接可行。 否则,接收方必须回应一个 OFPT_ERROR消息,此消息带有 OFPET_HELLO_FAILED的类型字段, OFPHFC_INCOMPATIBLE的字段以及一个解释数据状态的随机 ASCII 字符串,然后终止连接。
在交换机和控制器交换过 OFPT_HELLO消息并且有共同的版本数字之后, 连接设置就完成了 , 标 准 的Openflow 消 息 能 够 在 连 接 之 上 交 换 。 首 先 , 控 制 器 发 送 一 个OFPT_FEATURES_REQUEST 消息来取得交换机的数据路径 ID(见 7.3.1 )。

6.3.2 连接中断

当交换机与所有的控制器丢失连接,会导致 echo 请求超时, TLS(安全传输协议)握手超时,或者其他的连接失败,交换机根据当前运行状态和配置,必须立即进入“失败安全模式”或者“失败独立模式” 。在失败安全模式下, 交换机行为唯一的改变就是丢弃发向控制器的包和消息。流表项应在“失败安全模式”下依据定时设置继续会发生超时现象。在“失败独立模式”下,交换机使用 OFPP_NORMAL保留端口处理所有的包。换机话说,就是交换机作为传统以太网的交换机和路由器。 “失败独立模式” 一般只在 Hybrid 交换机上存在 (见 5.1 )。
当再一次连接控制器时,已有的流表项将保留。如果有必要的话,控制器可删除所有的流表项。
交换机第一次启动时,它会运行在“失败安全模式”或者“失败独立模式” ,直到它成功的连接到控制器。启动时流表项的默认设置内容不在本 Openflow 协议之内。

6.3.3 加密

交换机和控制器可通过 TLS连接(安全传输层协议)通信。交换机启动时初始化 TLS连接来连接控制器, TLS 连接默认 TCP端口是 6633。交换机和控制器通过交换由位置专一密钥签名的证书,来相互鉴权。每个交换机必须是用户可配置的,并携带控制器鉴权的证书(控制器证书)和另一个证书向控制器鉴权(交换机证书) 。
交换机和控制器可选择用普通 TCP来互通,此 TCP连接默认位于 TCP端口 6633,由交换机发起和初始化。当使用默认的普通 TCP连接,推荐使用其他安全措施来防止窃听,伪装控制器以及其他 Openflow 通道上的攻击。

6.3.4 多控制器

交换机可能与一个或多个控制器建立通信。多控制器模式可靠性更好,如果一个控制器连接失败,交换机还是能够继续运行在 Openflow 模式中的。控制器的 hand-over (切换) 机制由控制器自己管理,这能够使其从失败中快速恢复或者使其负载平衡。控制器通过现有规范之外的模式来调节对交换机的管理。多控制器的目的是帮助同步控制器的传输。多控制器的功能基于控制器容错和负载平衡,而不是基于 Openflow 协议之外的虚拟化。
当 Openflow 操作启动, 交换机必须连接到所有与其配置相关的控制器, 并且尽力保持与他们的连接。许多控制器发送 controller-to-swith 命令到交换机,有关此命令的回复消息或错误消息必须被返回通过相关的控制器连接。异步消息可能发送给多个控制器,为每一个Openflow 通道复制一个消息,当控制器允许时就发出去。
控制器默认的身份是 OFPCR_ROLE_EQUAL 。以这种身份,控制器能够完全访问交换机, 这对其他控制器是一样的。默认地,控制器接收交换机所有的异步消息(比如包输入消息,流删除)。控制器发送 controller-to-swith 命令来改变交换机的状态。 交换机与众控制器之间互不干涉,也不进行资源共享。
控制器可要求更换身份到 OFPCR_ROLE_SLAVE 。 这样,控制器以只读方式接入到交换机。
控制器默认不接收交换机的异步消息,除了端口状态消息。控制器拒绝执行发送数据或改变交 换 机 状 态 的 controller-to-swith 命 令 , 例 如 , OFPT_PACKET_OUT,OFPT_FLOW_MOD,OFPT_GROUP_MOD, OFPT_PORT_MOD, OFPT_TABLE_MOD请求,以及 OFPMP_TABLE_FEATURES 非空体复合请求必须拒绝。如果控制器发送以上命令中的一个,那么交换机必须返回一个携带OFPET_BAD_REQUEST类 型 字 段 和 OFPBRC_IS_SLAVE代 码 段 的 OFPT_ERROR消 息 。 其 他controller-to-swith 消 息 , 例如OFPT_ROLE_REQUEST,OFPT_SET_ASYNC and OFPT_MULTIPART_REQUEST 这些查询数据的消息,应该正常进行处理。
控制器也可更换身份为 OFPCR_ROLE_MASTER 。这个角色与 OFPCR_ROLE_EQUAL 相似的,可完全访问交换机,不同的是,控制器要确保它的角色是唯一的。当控制器换到此身份时,交换机让OFPCR_ROLE_MASTER控制器改变为OFPCR_ROLE_SLAVE,但是不会影响到OFPCR_ROLE_EQUAL 控制器。 当交换执行身份切换操作时, 没有消息生成发送发到正进行身份切换的控制器(大多数情况下控制器不再可到达) 。
每个控制器会发送 OFPT_ROLE_REQUEST 消息给交换机让其知道自己的身份,交换机必须记住每个连接控制器的身份 。控制器可能随时改变身份,只要在当前消息中提供generation_id 。
身份请求消息提供了一种轻量级机制来帮助控制器管理 选举进程,控制器互相协调来配置自己身份。交换机不能直接的改变控制器的状态,这是由另一个控制器发出的消息作用的结果。任何的从控制器或者对等控制器( equal controller )可选择自己的主控制器。交换机可能同时连接到多个对等控制器,或多个从控制器,但最多连接一个主控制器。主控制器和对等控制器能完全改变交换机的状态, 控制器没有分割交换机的机制 。如果主控制器需要作为唯一能改变交换机的控制器,其它控制器应该全是从控制器,而不能有对等控制器。
控制器可控制在 Openflow 通道中传输的异步消息的类型, 并改变上述的默认值。 通过异步配置消息( 6.1.1 )列出需要使能或过滤的消息类型的所有原因。通过这个特性, 不同的控制器可以接收不同的通知,主控制器可以选择性的禁用其不关心的通知,从控制器可以启动它想监控的通知。
为了检测主从控制器切换时产生的无序消息, OFPT_ROLE_REQUEST 消息包含了一个 64 位序列字段, generation_id ,来标识主控身份。作为主控选举机制的一部分,控制器(或者第三方)协调 generation_id 的分配。 generation_id 是单调递增的计数器:每次主控关系改变时,会分配一个新的(更大的) generation_id ,例如,每当指定一个新的主控制器,generation_id 会增加。
当 接 收 到 身 份 是 OFPCR_ROLE_MASTER和 OFPCR_ROLE_SLAVE控 制 器 发 来 的OFPT_ROLE_REQUEST消 息 , 交 换 机 必 须 将 其 包 含 的 generation_id 消 息 与 之 前 最 大 的generation_id 比较,若较小的话,则丢弃。 交换机必须用错误消息回应,错误消息的类型是 OFPET_ROLE_REQUEST_FAILED,代码是 OFPRRFC_STALE 。
下面的伪代码描述了交换机处理 generation_id 的行为。
交换机的启动:
generation_is_defined = false ;
接 收 到 身 份 是 OFPCR_ROLE_MASTER和 OFPCR_ROLE_SLAVE控 制 器 发 来 的OFPT_ROLE_REQUEST 消息,并携带一个给定的 generation_id ,代码 GEN_ID_X:

if (generation_is_defined AND
distance(GEN_ID_X, cached_generation_id) < 0) {
<discard OFPT_ROLE_REQUESTmessage>;
<send an error message with code OFPRRFC_STALE>;
} else {
cached_generation_id = GEN_ID_X;
generation_is_defined = true;
<process the message normally>;
}

distance() 作为计算卷序列号距离的操作定义如下:
distance(a, b) := (int64_t)(a - b) ;
I.e.distance ()表示序列号之间无符号的差异,被解读为一个有符号的二进制补码值。
当 a 大于 b 且满足小于“序列长度的一半” ,则为正值,若 a 小于 b 则为负值。
如果消息请求身份是对等身份,交换机则忽略 generation_id ,因为 generation_id 是用来协调主从身份转换的。

6.3.5 辅助连接

默认情况下, Openflow 通道是一个独立的网络连接。 通道可能由一个主连接和多个辅连接组成。辅助连接由交换机创建,有利于改善交换机的性能和充分利用交换机的并行性。
交换机到控制器的每个连接,都由 Datapath ID 和 Auxiliary ID 来确认。主连接必须设置 Auxiliary ID 为 0,而辅连接须有一个非零的 Auxiliary ID 和相同的 Datapath ID。辅助连接必须使用和主连接相同的 IP 地址,但是可以使用不同的传输方式, 例如,TLS,TCP,DTLS或者 UDP,这取决于交换机的配置。辅助连接应该有和主连接相同的目标 IP 地址和相同的传输目的端口,除非交换机配置了指定值。控制器必须识别带有非零 Auxiliary ID 的连接,并绑定到具有相同 Datapath ID 的主连接。
交换机不能在主连接完成建立之前启动辅连接(见 6.3.1 ),因为只有确保主连接存在,辅连接才会被设置和维持(见 6.3.1 )。辅连接的建立和主连接是相同的。如果交换机发现到控制器的主连接断了,则必须立即关闭所有到那个控制器的辅连接,这样使控制器正确的解决 Datapath ID 的冲突。
交换机和控制器必须接收所有连接的全部消息类型和子类型: 主连接和辅连接不会限制一个指定的消息类型和子类型。 但是,在不同的连接上不同的消息类型处理性能可能会不同。
交换机可能以不同的优先级来处理辅连接,例如优先级高的就优先处理其消息。使用OpenFlow 配置协议的交换机,可能随机的赋予辅连接优先级。
Openflow 请求的回应必须用相同的连接返回。连接之间是不同步的,不同连接的消息可能以任意的顺序来处理。一个 屏障消息 仅用于使用它的连接(见 6.2 )。使用 DTLS或 UDP的辅连接可能丢失或重排消息, Openflow 在辅连接上不提供排序或传输保证。 如果消息必须要按序处理,那么他们则通过相同的连接发送,此连接不重新对包排序,并且使用屏蔽消息。
在整个运行期间,控制器自由的使用各种交换机连接来发送消息,但是为了最大化交换机的性能,提出以下建议:

  1. 非包出消息( 流模型 ,统计请求)的控制器消息应通过主连接传送。
  2. 含有包入消息的包出消息,应从包入的连接发送出去。
  3. 其他的包出消息通过辅连接发送,通过某种机制保证同一个流的数据包映射到相同的连接。
  4. 如果需要的辅连接找不到,控制器应该利用主连接。
    交换机可自由的使用不同的控制器连接来发送消息,尽管有下面的指导建议:
  5. 所有非包出的 Openflow 消息应通过主连接传送。
  6. 所有包出消息通过不同的辅连接发送,但通过某种机制保证同一个流的数据包映射到相同的连接。
    建立在不可靠传输( UDP,DTLS)之上的辅连接有额外的限制和规则,这些限制和规则不
    适 用 于 TCP, TLS。 不 可 靠 的 辅 连 接 支 持 的 消 息 类 型 有 如 下 : OFPT_HELLO,
    OFPT_ERROR,OFPT_ECHO_REQUEST,OFPT_ECHO_REPLY,OFPT_FEATURES_REQUEST,
    OFPT_FEATURES_REPLY,OFPT_PACKET_IN,OFPT_PACKET_OUT 和 OFPT_EXPERIMENTER, 其他类型
    的不被规范支持。
    在不可靠的辅连接上, HELLO 消息在连接启动时被发送用来设置连接(见 6.3.1 )。如果Openflow 设备在接收到一个 HELLO消息之前,接收来自不可靠辅连接的另一个消息,则设备要 么 假 定 连 接 已 合 理 设 置,并且使用来自消息的版本号,要么返回一个携带OFPET_BAD_REQUEST 类型和 FPBRC_BAD_VERSION代码的消息。 如果 Openflow 设备从辅连接之上,接收到一个携带 OFPET_BAD_REQUEST 类型和 FPBRC_BAD_VERSION代码的消息,那么它必须发送一个新的 Hello 消息或者终止这个不可靠的辅连接(连接可能稍后重试) 。如果辅连接上的消息在所选时间(低于 5 秒)之内没有被接收,则设备必须发送一个新的 Hello 消息或者终止不可靠的辅连接。如果在发送一个 Feature Request 消息之后,控制器在所选时间之内没有收到一个 Feature Reply 消息,则设备必须发送一个新的 Feature Request 消息或者终止不可靠的辅连接。 如果在接收到消息之后, 设备在 30 秒内的所选时间没有接收任何消息,那么设备就终止不可靠的辅连接。 如果设备接收到一个已中止的不可靠辅连接消息,设备必须假定他是一个新的连接。
    使用不可靠的辅连接的 Openflow 设备,应尽可能遵循 RFC 5405 的规范。

6.4 流表修改信息 Flow Table Modification Messages

流表修改信息有以下类型:

enum ofp_flow_mod_command {
OFPFC_ADD= 0, /* 新流表. */
  OFPFC_MODIFY= 1, /* 修改所有匹配表. */
  OFPFC_MODIFY_STRICT= 2, /* 严格匹配通配符和修改条目优先级. */
  OFPFC_DELETE= 3, /* 删除所有匹配表. */
  OFPFC_DELETE_STRICT= 4, /* 严格匹配通配符和删除条目优先级. */
};

携带 OFPFF_CHECK_OVERLAP 标志设置的添加请求 (OFPFC_ADD),交换机必须首先检查请求表中任何重叠流表项。如果一个数据包同时匹配两个,而且两个项有相同的优先级,两个流表项就重叠。如果一个重叠冲突出现在已有流表项和添加请求之间,交换机必须拒绝添加,并且回馈一个 OFPET_FLOW_MOD_FAILED类型和 OFPFMFC_OVERLAP代码的 ofp_error_msg 。
对于没有重叠的添加请求,或者他们没有重叠的检查,交换机必须在请求表中插入流表项。如果在请求表中已经有了含有完全相同的匹配字段和优先级的一个流表项,则已有的流表项,包括其生存期, 必须从表中删除, 新的流表项将被添加。 如果设置 OFPFF_RESET_COUNTS
标志,流表项计数器必须清零,否则他们应该从替换的流表项中复制。作为添加请求的一部分,流表项删除不会生成 flow-removed 消息;如果控制器想要一个 flow-removed 消息,它应当在添加一个新流表项之前对旧的流表项发送一个明确的删除请求。
关于修改请求 (OFPFC_MODIFY或 OFPFC_MODIFY_STRICT) ,如果匹配项出现在表中,表项中的指令字段更新为请求的值,然而它的 cookie ,idle_timeout, hard_timeout, 标记,计数器, 和生存字段不发生改变。 如果 OFPFF_RESET_COUNTS标记被设定, 流表项计数器必须被清零。关于修改请求,如果当前请求表中没有流表项匹配这个请求,则没有错误记录,也没有流表修改发生。
对于删除请求 (OFPFC_DELETE或 OFPFC_DELETE_STRICT) ,如果一个匹配项出现在表中,它必须被删除,如果有 OFPFF_SEND_FLOW_REM 标记集,它必须发生一个流移除信息。对于删除请求,如果当前在请求表中没有流表项来匹配请求,则没有错误记录,也没有流表修改发生。
修改和删除流 flow- mod命令有非严格的版本 (OFPFC_MODIFYand OFPFC_DELETE) 和严格的版本 (OFPFC_MODIFY_STRICTor OFPFC_DELETE_STRICT) ,在严格的版本中,匹配字段集,所有匹配字段 , 包括他们的掩码、优先级,是和表项严格匹配的 , 只有一个相同的流表项被修改或删除。比如,发送一个移除表项的信息,如果没有字段能够匹配,则 OFPFC_DELETE命令就要从表中删除所有的流表项,而OFPFC_DELETE_STRICT命令只会删除一个应用在指定优先级数据包上的流表项。
关于非严格修改和删除命令,与流模式描述相匹配的所有流表项都会被修改和删除。在非严格版本,当流表项正好匹配或者比流模式命令描述的更多,一个匹配就会产生。在流模式中失配字段变为通配的,字段掩码是有效的,比如优先级等其他的流模式字段则被忽略。
比如,如果一个 OFPFC_DELETE命令去删除目标端口为 80 的所有流表项,那么通配所有匹配字段的流表项将不会被删除。 然而,通配所有字段的一个 OFPFC_DELETE命令将会删除一个匹配端口 80 的表项。同样的解释混合通配符和精确匹配字段也适用于单个和汇聚流数据请求。
目标组或输出端口可以有选择地过滤删除命令。如果输出端口字段包含一个值除了OFPP_ANY。匹配时它引入一个约束, 这个约束是 , 每个匹配流表项必须包含一个针对指定端口的输出行动。 这个约束只对直接与流表项关联的行动进行限制。 换句话说 , 交换机不能通过点到组的行动集递归 , 这可能已经匹配输出操作。 out_group, 如果不同于 OFPG_ANY, 对组引入了类似的限制行动。这些字段被 OFPFC_ADD,OFPFC_MODIFY 和 OFPFC_MODIFY_STRICT消息忽略。
删除和修改命令也能够通过 cookie 值过滤。如果 cookie-mask 字段包含一个值而不是 0.
这种约束就是流模式 cookie 字段中 cookie_mask 指定的位和流条目的 cookie 值必须相同。
换句话说 (flow_entry.cookie & flow_mod.cookie_mask) == (flow_mod.cookie & flow_
mod.cookie_mask)。
删除命令针对 table_id 可使用 OFPTT_ALL值来表示匹配的流表项将被从所有流表中删除。
如 果 流 表 修 改 消 息 指 定 一 个 无 效 的 table_id 。 交 换 机 必 须 发 送 一 个 带 有OFPET_FLOW_MOD_FAILED类型和 OFPFMFC_BAD_TABLE_ID代码的 ofp_error_msg 消息。
如果流修改消息在添加和修改请求中对 table_id 指定了 OFPTT_ALL,交换机必须发送相同的错误消息。
当向请求表中添加进入的流表项时, 交换机不能在请求表中找到空间。 交换机必须发送一个带有OFPET_FLOW_MOD_FAILED类型和 OFPFMFC_TABLE_FULL代码的 ofp_error_msg 消息。
如果流模式消息中请求指令不明白,交换机必须发送一个带有 OFPET_BAD_INSTRUCTION
类型和 OFPBIC_UNKNOW_INTS代码的 ofp_error_msg 消息。如果流模式消息中请求指令是不受支持的, 交换机必须发送一个带有 OFPET_BAD_INSTRUCTION类型和 OFPBIC_UNSUP_INTS代码的ofp_error_msg 消息。
如果请求指令包含 Goto-Table 和 next-table-id , 指向一个无效的表, 交换机必须返回一个带有OFPET_BAD_INSTRUCTION类型和 OFPBIC_BAD_TABLE_ID代码的 ofp_error_msg 消息。
如果请求指令包含 Write-Metadata , 而且元数据值或元数据掩码的值是不支持的, 交换机 必 须 返 回 一 个 带 有 OFPET_BAD_INSTRUCTION类 型 和 OFPBIC_UNSUP_METADATA或OFBIC_UNSUP_METADATA_MASK 代码的 ofp_error_msg 消息。
如果流模式消息指定的一个字段 , 匹配时在表中是不支持的,交换机必须返回一个带有OFPET_BAD_MATCH类型和 OFPBIC_BAD_FIELD代码的 ofp_error_msg 消息。如果流模式消息指定的 一个字 段, 匹配 时不止 一次, 交换机必 须返回 一个带 有 OFPET_BAD_MATCH类型 和OFPBIC_DUP_FIELD代码的 ofp_error_msg 消息。如果匹配交换机流消息指定字段 , 但未能指定相关的先决条件 , 例如指定一个 IPv4 地址而没有匹配 EtherType 到 0x800, 交换机必须返回一个携带 OFPET_BAD_MATCH类型和 OFPBMC_BAD_PREREQ 代码的ofp_error_msg 。
流模式特定的数据链路或网络地址一个随机位掩码匹配, 如果交换机不能支持 , 交换机必须 返 回 一 个 带 有 OFPET_BAD_MATCH类 型 和 OFPBMC_BAD_DL_ADDR_MASK或OFPBMC_BAD_NW_ADDR_MASK 的 ofp_error_msg 消息。如果 bitmasks 中指定不支持数据链接和网络地址就应使用OFPBMC_BAD_DL_ADDR_MASK 。如果流模式指定另一个字段的一个随机位掩码匹配不能支持 , 交换机必须返回一个带有 OFPET_BAD_MATCH类型和 OFPBMC_BAD_MASK 代码的 ofp_error_msg 消息。
如果流模式指定值不能匹配,例如,一个大于 4095 的 VLANID,与一个非保留值或两个高 位 比 特 设 置 一 个 的 DSCP值 , 交 换 机 必 须 返 回 一 个 带 有 OFPET_BAD_MATCH类 型 和OFPBMC_BAD_VALUE代码的 ofp_error_msg 消息。
如 果 任 意 行 动 作 用 到 交 换 机 的 一 个 不 再 有 效 端 口 , 交 换 机 必 须 返 回 一 个 带 有OFPET_BAD_ACTION类型和 OFPBAC_BAD_OUT_PORT 代码的 ofp_error_msg 消息。如果有关的端
口也许在将来会是有效的,例如当一个 linecard 添加到传统交换机 , 或动态添加一个端口到软交换机 , 交换机要么丢弃发送到该端口的数据包 , 要么立即返回一个 OFPBAC_BAD_OUT_PORT错误并拒绝此流模式。
如果流模式消息中的一个行动涉及到一个交换机没有定义的组,或是一个保留组比如OFPG_ALL,交换机必须返回一个带有 OFPET_BAD_ACTION类型和 OFPBAC_BAD_OUT_GROUP 代码的 ofp_error_msg 消息。
如果流模式消息的行动有一个无效的值 , 例如 Set VLANID 的行动值大于 4095,或用无效Ethertype 进 行 Push 行 动 , 交 换 机 必 须 返 回 一 个 带 有 OFPET_BAD_ACTION类 型 和OFPBAC_BAD_ARGUMENT 代码的 ofp_error_msg 消息。
如果一个流模式消息中的行动执行一个与匹配不一致的操作, 比如, 一个弹出 VLAN行动,而匹配没有指定 VLAN,或使用通配 Ethertype 的匹配来设置 IPv4 地址, 交换机可以选择拒绝此流模式并立即返回一个带有 OFPET_BAD_ACTION类型和 OFPBAC_MATCH_INCONSISTENT 代码的 ofp_error_msg 消息。任何不一致的行动对匹配数据包的影响没有定义,强烈建议控制器避免产生可能引起不一致行动的表项组合。
如果一个行动列表有一系列的行动, 而交换机不能按其指定次序支持 , 交换机必须返回一个带有OFPET_BAD_ACTION类型和 OFPBAC_UNSUPPORTED_ORDER 代码的 ofp_error_msg 消息。
在流模式消息处理期间发生任何其它的错误,交换机可能会返回一个带有OFPET_FLOW_MOD_FAILED类型和 OFPFMC_UNKNOWN 代码的 ofp_error_msg 消息。

6.5 组表修改信息 Group Table Modification Messages

组表修改信息有以下类型:

/* 组命令 */
enum ofp_group_mod_command {
  OFPGC_ADD= 0, /* 新组. */
  OFPGC_MODIFY= 1, /* 修改所有匹配组. */
  OFPGC_DELETE= 2, /* 删除所有匹配组. */
};

组可能含有零个或零个以上的储存段。没有储存段的组将不会更改与包有关的行动集。
如果交换机支持的话,一个含有储存段的组他们本身也可转向其他的组。
行动集对每个储存段要验证,使用的规则就是与流模式相同的规则( 6.4 节),并进行组指定的校验。如果在一个储存段中一个行动是无效的或不支持,交换机应当返回一个ofp_error_msg 和 OFPET_BAD_ACTION类型,以及相应的错误代码。 ( 见 6.4)
对于 add 请求(OFPGC_ADD) ,如果组表中已经有了指定标识符的组表项, 交换机就会拒绝添加组表项。并且发送一个带有 OFPET_GROUP_MOD_FAILED类型和 OFPGMFC_GROUP_EXISTS代码的 ofp_error_msg 消息。
对于修改请求 (OFPGC_MODIFY) ,如果组表中已经有了指定标识符的组表项,那么包括它的类型和行动储存段,必须被移除,然后新组表项被添加。如果指定标识符的组中此组表项不存在 ,交换机必须拒绝此流模式并发送一个带有OFPET_GROUP_MOD_FAILED类 和OFPGMFC_UNKNOWN_GROUP 代码的ofp_error_msg消息。
如果一个指定的组类型是无效的, (比如:指定组类型中没有定义的像 权重 这样的字段)交换机必须拒绝添加组表项,并且发送一个 ofp_error_msg 伴随 OFPET_GROUP_MOD_FAILED类型和OFPGMFC_INVALID_GROUP 代码。
如果交换机在所选组中不支持非均等负荷共享(存储段的权重不等于 1),必须拒绝添加这个组表项 ,必须发 送 一 个 带 有 OFPET_GROUP_MOD_FAILED类 和OFPGMFC_WEIGHT_UNSUPPORTED 代码的 ofp_error_msg 消息。
如 果由于缺少空间,交 换 机 不 能 添 加 到 来 的 组 表 项 , 交 换 机 必 须 发 送 一 个 带 有OFPET_GROUP_MOD_FAILED类和 OFPGMFC_OUT_OF_GROUPS 代码的 ofp_error_msg 消息。
如果由于组储存段数量限制的约束 ( 硬件或其他原因 ) ,一个交换机不能添加进来的组表项,交换机必须发送一个带有 OFPET_GROUP_MOD_FAILED类和 OFPGMFC_OUT_OF_BUCKETS 代码的 ofp_error_msg 消息。
如果由于不支持推荐的活动配置,交换机不能添加组 , 交换机必须发送一个带有OFPET_GROUP_MOD_FAILED类和 OFPGMFC_WATCH_UNSUPPORTED 代码的 ofp_error_msg 消息。这
包括为不支持活动性的组指定 watch_port 或 watch_group, 或对 watch_port 中指定不支持活动性的端口 , 或对 watch_group 中指定不支持活动性的组。
对于删除请求 (OFPGC_DELETE) ,如果所标识组的组表里没有组表项 , 就不会记录错误 , 也不会发生组表修改。否则 , 组被删除 , 包含在组行动中所有组流表项也会被删除。组类型不需要在删除请求中指定。 删除不同于没有储存段的添加或修改 , 以后试图添加组标识符不会造成组已存在的错误。 如果希望使用它有效地删除保留在流表项里的组 , 组可以通过发送一个无指定储存段的修改来删除。
用单个消息删除所有组的话,需要指定 OFPG_ALL作为组值。
如果交换机支持的话,组可以串联起来 , 至少有一组指向另一组 , 或有更复杂的结构。例如一个快速重路由组可能有两个储存段,每一个指向选择的组。如果一个交换机不支持串联组 的 组 , 它 必 须 发 送 一 个 带 有OFPET_GROUP_MOD_FAILED类 型 和OFPGMFC_CHAINING_UNSUPPORTED 代码的 ofp_error_msg 消息。
一个交换机可支持检测组成链时不能形成循环:如果组将创建一个转发循环 , 交换机必须拒绝组并且必须发送一个带有 OFPET_GROUP_MOD_FAILED 类型和 OFPGMFC_LOOP代码的ofp_error_msg 消息。如果交换机不支持这样的检查 , 则转发行为就是未定义的。
一个交换机可支持检测被其它组转发的组没有删除: 如果交换机由于组关联另一个组而不能删除,必须拒绝删除组的表项,必须发送一个带有 OFPET_GROUP_MOD_FAILED 类型和OFPGMFC_CHAINED_GROUP 代码的 ofp_error_msg 消息。如果交换机不支持这样的检查 , 则转发行为就是未定义的。
若支持组的快速故障切换需要在线监测 , 以确定要处理的指定储存段。 其它组类型不需要实现在线监视 , 但可以选择应用它。如果一个交换机不能实现在线检查组中的任意储存段 , 它必须拒绝组并返回一个错误。确定活跃的规则包括:
一个端口被认为是活的如果它端口状态设置为 OFPPS_LIVE标志。端口活性可由交换机 OpenFlow 部分之外的代码管理,代码由 OpenFlow 规范之外来定义,如生成树或KeepAlive 机制。如果交换机某个端口活跃机制认为端口不活跃,此端口就必须不能认为活跃 (OFPPS_LIVE 标志必须未设置 ), 或者端口配置位OFPPC_PORT_DOWN 表示端口已关闭 , 或者端口状态 OFPPS_LINK_DOWN显示链接已拆除。
如果 watch_port 不是 OFPP_ANY而且端口监测是活跃的,或者 watch_group 不是OFPG_ANY而且组监测是活跃的,则存储段就认为活跃。
如果至少一个储存段是活跃的则一个组就认为是活跃的。
通过监控不同端口的状态控制器可以推断组的活性状态。

6.6 测量修改信息 Flow Table Modification Messages

测量修正信息有以下类型:

/* 测量指令 */
enum ofp_meter_mod_command {
  OFPMC_ADD,/* 新测量. */
  OFPMC_MODIFY,/* 修改指定的测量. */
  OFPMC_DELETE,/* 删除指定的测量. */
};

对于添加请求 (OFPMC_ADD), 如果指定测量标识符的测量项已经存在,交换机必须拒 绝 添 加 测 量 项 , 并 且 必 须 发 送 一 个 含 有 OFPET_METER_MOD_FAILED类 和OFPMMFC_METER_EXISTS码的ofp_error_msg 消息。
对于修改请求 (OFPMC_MODIFY), 如果指定测量标识符的一个测量项已经存在 , 这个测量项 , 包括其 带宽 , 必须删除 , 添加新测量项。 如果指定表标识符的测量项不存在 , 那么交换 机 必 须 拒 绝 meter mod 并 且 发 送 一 个 含 OFPET_METER_MOD_FAILED类 和OFPMMFC_UNKNOWN_METER 码的 ofp_error_msg 消息。
如果交换机由于缺少空间而不能添加进入的测量项,交换机必须发送一个带有OFPET_METER_MOD_FAILED类和 OFPMMFC_OUT_OF_METERS 代码的 ofp_error_msg 消息。
由于 带宽 数量限制的约束 (硬件和其他方面) ,交换机不能添加进入的测量项, 必须拒 绝 添 加 测 量 项 , 并 且 发 送 一 个 带 有 OFPET_METER_MOD_FAILED类 和OFPMMFC_OUT_OF_BANDS 码的 ofp_error_msg 消息。
对于删除请求 (OFPMC_DELETE) ,如果指定测量标识符的测量项没有存在 , 就没有错误记录, 也没有表发生修改。 否则, 将删除测量 , 在指令集中包含此测量的所有流也会被删除。
对于 delete 请求只需要指定测量标识符 , 其他字段如 带宽 可以省略。
用 OFPM_ALL作为测量值的单个消息可删除所有的测量。虚拟的测量永远不会删除, 当删除所有的测量时,也不会消除。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335