流的概念:
流表:针对特定流的策略表项的集合,负责数据包的查找与转发。
一张流表包含了一系列的流表项(flow entries)
流表项包括三个域:
针对交换机中的每张流表、每个数据流、每个设备端口、每个转发队
列进行维护,用于统计数据流量的相关信息:
用于指示交换机在收到匹配的数据包后应该如何对其进行处理
必备动作(Required Actions) 、可选动作(Optional Actions)
动作转发,与交换机的端口直接相关。OpenFlow交换机的端口是交换机传递数据包的网络接口。 交换机通过接口和其他交换机建立逻辑连接
端口(Ports):交换机传递数据包的网络接口,交换机通过接口和其他交换机建立逻辑连接:
- 物理端口 - 逻辑端口: 是对物理端口的虚拟化,提高可复用性,逻辑端口的数据包需要有tunnel_id; - 保留端口 :指定通用的转发动作(包括:ALL、CONTROLLER、TABLE、IN_PORT、ANY、LOCAL、NORMAL、FLOOD)。
OpenFlow保留端口:
ALL:转发给所有出端口,但不包括入端口 CONTROLLER:封装数据包并转发给控制器 TABLE:对packet_out数据包执行流表操作 LOCAL:转发给本地的网络栈; IN_PORT:从入端口发出 NORMAL:利用交换机的传统转发机制处理数据包 FLOOD:按照最小生成树从设备出端口洪泛发出
每个包按照优先级依次去匹配流表中表项,匹配包的优先级最高的表项即为匹配结果。匹配成功,对应的计数器将更新,同时实施转发动作;如果没能找到匹配的表项,则转发给控制器。
包头解析是为了得到数据分组的12元组(包头域)
1.初始化包头 2.根据以太网类型得到VLAN或三层IP的信息 3.根据IP分组头中的协议类型,确定是TCP/UDP/ICMP协议 4.得到四层的TCP/UDP的源目的端口号或者ICMP类型和编码
组表号(Group Identifier):一个32位无符号整数,组表项的唯一标识。 组表类型(Group Type):表明了对数据包的处理行为。其中必须支持的动作包括all和indirect,可选动作包括select和fast failover; 计数器(Counters):被该组表项处理过的数据包的统计量。 动作桶(Action Buckets):一个Action Bucket的有序列表,每个Action Bucket又包含了一组Action集合及其参数 组表可以包含0个或多个动作桶,除了 indirect 类型的桶只能有一个动作。一个组表没有动作桶默认是丢弃数据。 一个桶的典型使用是包含一个可以修改数据包的动作和一个将数据转发到另一个端口的动作。动作桶也可以包含一个动作,这个动作可以调用另一个组的,前提是交换机支持这种组表调用链。一个没有动作桶的组表是合法的,一个动作桶没有转发动作或别的动作,会默认丢弃掉匹配的数据包。
1. 节省流表空间 组表的能力就可以存储多个动作,当匹配到一个合适的动作后可以执行多个动作,优化了流表一个匹配+一个动作的工作模式。 2. 数据包复制 组表可以将进入的流量复制成多份,并对每一份单独处理。特定场合下如流量分析,可以一边将流量正常转发,一边将流量导入到某一个分析机中。 假如你想发送两份数据包的副本(copy),一个副本发送到目标地址,另一个副本发送到网络分析器,这个时候需要对这两个副本做不同的封装--一个副本需要添加VLAN header,另一个不需要(或者需要添加不同的VLAN ID)。如果在组表中做这个,你需要在所有的流表中创建不同的表项用于不同的封装;当你添加或者删除网络分析器时,需要找到所有的相应流表项并且进行修改。 如果用组表呢?创建一个ALL的组将所有的目标地址和网络分析器包含进去,group table中的每一个表项都有对于其特定的副本所要执行的actions:添加VLAN,设置不同的VLAN ID等等。当flow table查找到这条表项时,将packet转发至这个组表中,如果中途添加或者删除网络分析器,只需要在组表中进行修改而不需要动流表 3. 容错能力-备用端口/路径 组表有识别up端口和down端口的能力,可以在up的端口down掉之后将选择一个新的up端口转发流量。 例如:如果一个数据包应该在端口1离开交换机,但是这个端口down掉了,你想要将数据包通过端口2发送出去。如果用流表的话,当端口1down掉,需要找到所有含有“发往端口1”的流表项,全部修改成端口2,这个操作是很复杂的。这个时候,需要定义一个“1st live” group来表示这种容错行为,然后将所有的流表项的规则指向该组表。只要端口1正常,group会把所有的数据包发往端口1,如果端口1 down掉,将所有数据包发往端口2,流表没有任何变化。 4. 负载分流 组表可以选择动作中的某一个动作执行,在负载的场景下就可以通过转发到不同的端口实现后端流量负载。
• all: 执行组表中所有的动作。这种类型通常被用在组播或者广播转发。数据包非常高效的复制给每一个桶。每一个数据都被组表中的动作桶执行。如果一个动作是直接将数据包转发到进入的端口,这个包的复制会被放弃。如果控制器中写入了转发到进端口的流表,组表必须包含一个转发动作为OFPT_IN_PORT的保留动作。 • select: 执行组表中的一个动作桶。数据包被组表中一个单个的桶处理,具体是哪一个动作通取决于交换机的选择算法。所有关于选择算法的配置和状态都是独立于OpenFlow协议之外的。 • indirect: 执行组表中的一个定义的动作桶。这种组表只支持一个动作桶。允许多个流表条目或者组表指向这个id,支持更快,更高校的聚合。这种组类型是所有组类型中最高效的方式。 • fast failover: 执行第一个活动的桶。每个动作桶和特殊的端口或组表有关系,可以控制动作桶的存活。动作桶有序的定义在组表中,第一个和活动的端口有关系的桶会被选择。这种类型可以修改交换机的流表而不需要控制器下发流表。如果没有动作桶是活动的,数据包会被丢弃。
计量表号(Meter Identifier):一个32位无符号整数,计量表项的唯一标识。 计量带(Meter Bands):一个无序的Meter Band集合,每个Meter Band指明了带宽速率以及处理数据包的行为。 计数器(Counters):被该计量表项处理过的数据包的统计量