本博客属于本人学习SDN的学习记录,仅供参考。
软件定义网络(SDN)研究进展
SDN 的主要思想是实现对转发设备的数控分离,控制层由原来的分布式协议(如 OSPF 和 BGP)管理变更为逻辑上高度集中的软件控制器管理。
OSPF属于IGP协议,是链路状态路由协议,一般运行在AS自治系统内部,采用SPF算法保证了在AS内部不会产生环路。由于OSPF协议时每台路由器自身计算出来的,所以过滤路由非常麻烦。
BGP属于EGP协议,是距离矢量路由协议,在设计考虑到可能形成环路问题,故此为BGP添加了许多属性保证不会产生环路,通常应用在AS之间,用于互联网选路的协议,可以通过更改BGP属性来影响路由选路问题,BGP本身不计算路由,因此依靠引路其他路由,所以过滤路由是比较方便地,而且依靠BGP属性的应用,很容易实现数据分流。
图1展示了 SDN 的完整架构,主要可划分为三个层面和两个接口,三层是指应用层、控制层以及数据层,两接口是指北向和南向接口。
三个层面:
应用层:
应用程序部署在 SDN 最顶层的应用层,它们一方面借助控制器所获取到的相关网络信息来执行内部决策,另一方面又通过北向接口指定对控制器的网络需求。典型的 SDN 应用程序主要包括网络监控器、负载均衡器、防火墙等。
网络监控软件是指针对局域网内的计算机进行监视和控制;针对内部的电脑上互联网以及内部行为与资产等过程管理;包含了上网监控(上网行为监视和控制、上网行为安全审计)和内网监控(内网行为监视、控制、软硬件资产管理、数据与信息安全);
负载均衡,英文名称为Load Balance,其含义就是指将负载(工作任务)进行平衡、分摊到多个操作单元上进行运行,例如FTP服务器、Web服务器、企业核心应用服务器和其它主要任务服务器等,从而协同完成工作任务。负载均衡构建在原有网络结构之上,它提供了一种透明且廉价有效的方法扩展服务器和网络设备的带宽、加强网络数据处理能力、增加吞吐量、提高网络的可用性和灵活性。
北向接口:
北向接口是专为研究人员开发自定义功能的应用程序而开放的接口,但由于控制器的种类繁多,且实现方式各异,所以目前该接口还没有公认的标准。
控制层:
控制层的关键组件是集中式的软件控制器,它除了要为顶层的应用程序供应所需求的网络信息之外,还要将网络需求转换为配置命令通过南向接口下发给 SDN 交换机,以便对网络流量进行调度。
网络流量就是网络上传输的数据量。网络流量的大小对网络架构设计具有重要意义,就像要根据来往车辆的多少和流向来设计道路的宽度和连接方式类似,根据网络流量进行网络的设计是十分必要的。
南向接口:
南向接口是控制层和数据层通信的信道,南向协议同样不唯一,其中 OpenFlow 凭借其灵活性得到了业界的广泛认可。
数据层:
最底层的数据层包括所有的 SDN 网络设备和电缆。尽管所有的 SDN 网络设备仍是基于第二层、第三层的包头转发数据包,但是它们统一的使用 SDN 交换机替代了传统的路由器和交换机。
OpenFlow 协议作为一个开放性的协议,打破了传统网络设备厂商对设备能力接口的壁垒。OpenFlow 协议始发于 2009 年,目前 1.0 版本和 1.3 版本的流行度最高。
由于 OpenFlow 协议和 SDN 两者经常伴随出现且具有高度的契合,人们曾一度误认为 OpenFlow 协议等同于 SDN。事实上,它只是一种具有高认可度的南向协议,只属于 SDN 这个研究领域的一个子集,其最关键的要素包括流表、交互消息和安全通道(下面的内容以 OpenFlow 1.3 版本为例)。
流(Flow):指在一段时间内,经过同一个网络的一系列具有相同属性的顺序发送的报文集合;
流有老化时间,如果具有相同属性的报文隔了足够长时间发,假设这个时间已经超过了老化时间了,那对于交换机来说,这已经是一条新的流了;
流表(Flow Table):流表就是芯片中一张张的转发表,每一张流表都由很多条流表项组成,比如一张流表有16K,就是说这张流表有16K条流表项;
流表项(Flow Entry):流表项是流表的最小单位,每条流表项对应了网络中传输的一条流,流表项是OpenFlow中最核心的元素。
流表项的组成部分是指控制器和交换机之间传输的数据结构,是对流表项的逻辑描述,并不是跟芯片转发表中的实际字段一一对应;
OpenFlow 1.3 版本支持多级流表,每个流表又包含多个流表项,具体结构如图2所示,分别是:
多级流表将数据包的处理逻辑划分为多个子逻辑,并由多张流表分别来匹配和处理,从而使得数据包的处理变成了一条流水线。多级流表的设计使得流表项聚合成为可能,节省了流表空间,也提高了编程处理逻辑的灵活性。
匹配字段:一组协议域的组合,用来识别该条表项对应的流条目。
匹配字段包括报文本身的信息(如MacDa,MacSa,Vlan,IPDA,IPSA等)以及跟报文关联的字段。如报文进来的port,前一张流表传过来的属性数据,同一张流表中,里面不同的流表项的匹配字段可以是不同的,也可以相同。
协议域,即同一个域下的各个协议在一个协议域中,但不一定在一层中,如IP协议和TCP协议都在Internet协议域中,但是他们不在一层。
协议域结构的功能:设置协议族的标识(如AF_INET等),设置域名称,对协议域的各种操作或者控制函数指针(根据协议域的不同,函数指针指向的函数会不同)。
优先级:定义流表项的匹配顺序。
一个报文在流表进行匹配查找的时候,是从上到下顺序查找的,优先级就是用来标志流表项之间的顺序关系的,优先级相同的流表项是平等的,没有顺序关系;控制器往交换机下发流表项的时候,用优先级告诉交换机该条流表项在流表中存放的相对位置。
计数器:保存流条目相关统计信息。
计数器是管理员用来观察监控网络负载情况的非常重要的工具,原则上每条流表项都应该对应一个计数器,来表示属于这条流的报文已经收到了多少个以及各种其他统计数据,比如多少字节,多少错误的包等。
指令:流表项对流执行的行动。
OpenFlow里面定义的指令有以下几种:
Meter:用于测量该Flow的速率并执行相应的动作。按照OpenFlow标准术语,每个Meter包含几个Band,每个Band对应一个Rate(速率)和动作,Band的意思是如果所测量的Flow速率超过了指定的Rate,就执行相应的动作,动作可以是drop(丢包)或者dscp remark(改写IP头部中的dscp值);
Apply-Action:立即对报文执行一个Action List(动作列表)里面指定的所有Action,这些Action执行的结果可能影响也可能不影响下一级流表查找;Apply-Action的一个例子是,每条流都出一个Counter(计数器),立即匹配该流对应的报文数量进行统计;
Write-Action:并不立即对报文执行动作,而是把一个Action list里面的多个action放到一个action set动作集合中,等到所有流表都出来完了,再一次性处理这个action set里面所有action;如果不同的流所放的action有冲突,那么后面的覆盖前面的;
Clear-Action:如果某条流想把前面的所有流表处理后产生的所有Action Set都清除掉,就要执行Clear-Action的指令;
Write-metadata(metedata可意译为描述信息):代表一条流独一无二的特征ID;用来在多级流表之间传递以达到关联多级流表的目的。
Goto-Table:继续下一级指定流表的处理。唯一一个要求必须支持的指令;只支持单级流表的时候,这个指令没有意义;
超时时间:流表项可存活的最大生存时间。
最大生存时间:控制器会下发流规则,交换机的流表空间是有限的,不能一直占用,一般最大生存时间为5秒。
每套流表项可以被老化,timeout就是表示该流的老化时间。OpenFlow定义了两种老化时间,hard timeout和idle timeout 前者标识从该流表项创建开始,到了这么长时间后,无条件删除;后者表示,如果在这么长时间内,没有任何报文匹配过该流表项,那就删除;前者可以靠软件做,后者可以必须要靠硬件来做;
附属属性:用于过滤流统计数据。
Cookie是被Controller向Switch来传递流表项相关的操作信息的,比如修改Flow,删除Flow等;这个属性不会在报文转发的时候被使用,仅仅用于Controller和交换机之间传递消息;
1、当数据包抵达交换机时,会按流表的优先级顺序匹配,匹配的内容主要是各类网络协议的源地址、目的地址、协议号以及交换机的端口等。
2、若匹配成功,则更新计数器并执行流表项的指令。
3、若指令中还存在流表跳转的动作,则进入到下一级流表中继续执行类似的处理。
4、否则, 表示流水线处理完成,执行相应的动作集。
5、此外,若匹配失败,则判断是否存在 Table-Miss,存在则交给控制器处理,否则丢弃数据包。
整个处理流程如图 4 所示。
OpenFlow中定义三大类端口:
物理端口(Physical Port):交换机面板上所有对外可见的物理端口(带外管理端口除外);
逻辑端口:其中一个例子就是,Tunnel;
保留端口里面有多种端口,Controller Channel(连接Controller的通道,可以是带内业务口,也可以是独立的带外管理口)就是一种保留端口;
组group类似流表;
group中有一个词bucket,bucket指一个action list;
ALL 意思是转发到该group所包含的所有bucket中,可以使用组播实现;
Select:意思是转发到该group所包含的所有bucket中的一个;
Indirect:在多个Flow中共享Action,这种类型的Group只包含一个Bucket;
Fail-over:保护倒换,就是在正常状态中,报文只从这个group的一条路径转发出去,一旦这条路径断了,备份路径马上顶上;
控制器与交换机交互的消息分为三类:第一类是控制器至交换机的消息,第二类是异步消息,第三类是对称消息。
第一类消息由控制器发起,作用是查询交换机的状态以及对其进行配置。例如,用于获取交换机自身特征的 Features 消息、对交换机进行配置的 Configuration 消息以及请求交换机统计信息的 Read-State 消息等。
Features:Controller用这个消息类型询问交换机能支持的类型
Configuration:Controller用这个消息类型配置交换机或者查询交换机配置参数
Modify-State:Controller用这个消息类型来操作流表(add/delete/modify)和group表,以及Ports属性等;
Read-State:Controller用这个消息类型来获取交换机各种状态消息,如Counter
Packed-out:Controller用这个消息类型向外发送匹配某条流表项的数据报文;
Barrier:Controller用这个消息类型保证一些其他消息之间的顺序;如B消息依赖与A,那么Controller先朝交换机发送消息A,然后在发送一个Barrier消息,交换机等消息A被执行完后才发送一个对Barrier消息的回复,Controller收到回复后,才会继续发送消息B;
Role-Request:当交换机连了多个Controller的时候,Controller用这个消息类型向交换机通告自己的角色;
Asynchronous-Configuration:用于Controller告诉交换机对交换机发来的哪些消息感兴趣;
第二类消息由交换机发起,主要目的是将发生在交换机上的各种事件通知给控制器。例如,上传数据包的 Packet-In 消息、上报交换机端口状态的 Port-Status 消息以及上报流表项过期的 Flow-Removed 消息等。
Packet-in:当有报文匹配某条流表项,该流表项action是output to Controller-Port时,这个报文就被通过Packet-in的消息发送到Controller
Flow-removed:当某个流表项被删除的时候(老化或者Controller主动要求删除),一个Flow-removed的消息就会被发送到Controller;
Port-status:当端口状态发生变化的时候,交换机用这个消息类型告诉Controller通告状态变化,比如Link down/up;
Error:当交换机发生了一些错误的时候,发送这个消息到Controller;
第三类消息可由任意一方发起,且接收方必须应答。常见的第三类消息主要有用于建立双方连接的 Hello 消息、确认双方连接状态的 Echo 消息以及用于实现附加功能的 Vendor 消息等。
Hello:Controller或者交换机启动的时候,互发hello消息,通知对方启动了;
Echo:通过发Echo以及得到reply,确认对方的连接没有问题,也可以用来测量连接延时;
Experimenter:用来让产家进行私有扩展。
Master:一台交换机所连接到的所有Controller中,只能有一个Master,他对交换机拥有完全的操作权限;
Slave:一台交换机所连接到的所有Controlller中,可以有多个Slave,它们对交换机只有读取状态和被动接受交换机消息的权限,不能对交换机进行配置;一旦Master死掉,其中一台Slave就会被选举为Master,接替原来Master继续工作,每个Slave可以接受不同的消息类型,从而在个Slave之间进行负载分担;
Equal:有的网络希望有多个Controller都能对交换机进行配置,以便负载分担,这种情况,这些Controller可以被配置为Equal角色,一台交换机允许同时连接到多个Equal角色的Controller,这些Controller对交换机拥有跟Master一样的功能;
安全通道主要负责各种交互信息的传输。安全通道的连接可以单纯地只使用传输控制协议,也可以附加使用传输层安全协议对消息进行加密。 目前安全通道主要有两种部署模式:带外(Out of Band)模式和带内(In Band)模式。
传输控制协议(TCP,Transmission Control Protocol)是为了在不可靠的互联网络上提供可靠的端到端字节流而专门设计的一个传输协议。
传输层安全协议:TLS/SSL
TLS (和 SSL) 协议位于应用程序协议层和 TCP/IP 层之间,可以在其中保护应用程序数据并将其发送到传输层。 由于协议在应用程序层和传输层之间工作,因此 TLS 和 SSL 可以支持多个应用程序层协议。
TLS 和 SSL 假定使用面向连接的传输(通常为 TCP)。 协议允许客户端和服务器应用程序检测以下安全风险:
消息篡改
消息拦截
消息伪造
TLS 和 SSL 协议可以分为两层。 第一层由应用程序协议和三个握手协议组成:握手协议、更改密码规范协议和警报协议。 第二层是记录协议。
两者主要的区别在于带外模式是指每台 OpenFlow 交换机与控制器之间都有一条单独的通道,而带内模式是指所有交换机共享同一条通道。具体如 图 5 所示,虚线代表安全通道,实线代表的是交换机之间的数据通道。
图 6 描述了基于 OpenFlow 的通信流程。在该图所示的网络拓扑中,主机 H1 与 H2 想要成功通信需要经历以下步骤:
②由于匹配不成功,交换机将数据包封装在 Packet-In 消息中上交给控制器。
③控制器解析该消息后,计算出通信的最佳转发路径,即主机 H1→交换机 A→交换机 C→主机 H2。
④控制器下发处理指令到这条最佳转发路径所包含的交换机 A 和 C 上,约束数据包走该路径转发。
⑤交换机 A 和 C 根据控制器所下发的处理指令转发该数据包,最终主机 H1 和主机 H2 得以成功通信。
需要注意的是,在第④步中控制器下发处理指令给交换机时有两种处理方式,如图 7 所示。
一种是下发 Flow-Mod 消息为交换机安装流规则,以便于之后能够处理即将到来的类似数据包,而无需反复的请求查询控制器,这种方式适用于目的设备信息已知的流,即能够从当前网络中找到目的设备所直连的交换机。
Modify-State消息属于控制器与交换机之间的消息类型,控制器通过Port-mod消息用来管理端口状态,通过Flow-mod消息增删交换机的流表项,考虑到流表在OpenFlow的重要意义,在此针对Flow-mod消息进行详尽分析。
前4个字段,表示OpenFlow消息的通用报头。
wildcard字段,表示匹配时12元组的掩码位,被掩盖掉的元组不参加匹配。
从in_port到tp_dst字段,表示流表项12元组的信息。
cookie字段,在处理数据分组时不会用到,控制器通过该字段来过滤流的统计信息。
command字段,表示对流表的操作,包括增加(Add)、删除(Delete)、修改(Modify)等。
idle_time字段,表示当这条流表项在这段时间内没有匹配到数据分组,则该流表项失效。
hard_time字段,表示自流表项下发后只要过了这段时间即刻失效。
priority字段,表示该流表项被处理的优先级,原则上优先级越高,所属的Table号就越小。
buffer_id字段,表示对应Packet-in消息的buffer_id。
out_port字段,仅在command为Delete或者Delete Strict时有效,表明当某表项不仅匹配了Flow-mod中给出的12元组,且转发动作中指定端口等于该out_port的动作时才予以删除,即对删除操作的一种额外限制。
flags字段,该字段为标志位,OpenFlow v1.0中包括3项:OFPFF_SEND_FLOW_REM(流表失效时是否向控制器发送Flow-removed消息),OFPFF_CHECK_OVERLAP(交换机是否检测流表冲突),OFPFF_EMERG(该流表项将被存于Emergency Flow Cache中,仅在交换机处于紧急模式时生效)。
actions字段,该字段是个数组,表示要对满足过滤条件的流做的动作列表,actions[0]即代表其中第一个动作。
另一种是控制器直接下发 Packet-Out 消息给交换机以对数据包进行泛洪处理,这种方式适用于目的设备信息未知的流,即无法从当前的网络中找到目的设备所直连的交换机。
使用Packet-In消息的目的是为了将到达OpenFlow交换机的数据包发送至OpenFlow控制器。以下2种情况即可发送Packet-In消息。
1、不存在与流表项一致的项目时(Table-miss),OFPR_NO_MATCH
2、匹配的流表项中记载的行动为“发送至OpenFlow控制器”时,OFPR_ACTION
发送Packet-In消息时OpenFlow交换机分为两种情况,一种是缓存数据包,一种是不缓存数据包。如果不通过OpenFlow交换机缓存数据包,那么Packet-In消息的buffer_id字段设置为-1,将整个数据包发送至OpenFlow控制器。
如果通过OpenFlow交换机缓存数据包,那么以通过SET_CONFIG消息设置的miss_send_len为最大值的数据包数据将发送至OpenFlow控制器。
miss_send_len的默认值为128。未实施SET_CONFIG消息的交换时,使用该默认值。
Packet-Out消息是从OpenFlow控制器向OpenFlow交换机发送的消息,是包含数据包发送命令的消息”。
若OpenFlow交换机的缓存中已存在数据包,而OpenFlow控制器发出“发送该数据包”的命令时,该消息指定了表示相应数据包的buffer_id。使用Packet-Out消息还可将OpenFlow控制器创建的数据包发送至OpenFlow交换机。此时,buffer_id置为-1,在Packet-Out消息的最后添加数据包数据。
交换机处理带宽:芯片决定,无法优化
流表项数量:芯片决定,无法优化
流表项下发能力:即每秒能安装多少条流表项;这个指标跟OpenFlow交换机收包/处理包能力、芯片SDN对流表项处理能力,Contoller软件处理以及CPU主频有很大关系;可以通过提高CPU主频或者优化软件来提高;
To-Controller报文转发:有些报文在交换机里面匹配到某条流表项,这条流表项的动作把报文发送到Controller,Controller经过处理后可能会在把报文通过交换机转发出去;这个转发性能决定Controller和交换机两个元素;
控制器是 SDN 的核心,致力于保障网络的无差错运行。目前主流控制器包 括 Floodlight[55]、POX[56]、ONOS[57]等。下面介绍主要以 Floodlight 为代表,对 SDN 控制器作简单介绍。
Floodlight 发布于 2012 年,尽管出现的时间较早,但目前知名度依旧很高。 Floodlight 基于 Java 所编写而成,总体规模不算特别复杂,易于上手,因此在学术界得到了广泛使用。
Floodlight 的架构如图 8 所示,主要包括核心服务、模块应用以及 REST 应用。Floodlight 具有四个重要特点:
一是便捷的模块加载系统,有利于研究人员根据实际需求实现对网络功能的扩展;
二是支持多种虚拟或实际的转发设备, 普适性较强;
三是支持对混合网络场景的处理,即在同一网络中既包含 OpenFlow 设备,又包含传统的转发设备;
最后是其源代码采用的是一种从 Java 底层所实现的多线程体系,具有较高的性能。
在 Floodlight 中,能够对 Packet-In 消息进行处理的模块必须要先注册一个 OpenFlow 消息的监听器,如链路发现、拓扑管理、设备管理、负载均衡、防火墙以及转发模块等都注册了该功能,这样各个模块就能根据所监听到的消息完成各自的处理任务,处理顺序如图 9 所示。
当发生不匹配时,由交换机上交的 Packet-In 消息首先会进入 Floodlight 的链路发现管理模块,该模块专门处理有效载荷为 LLDP 数据包的 Packet-In 消息, 目的是发现和维护整个网络中所有链路的状态。
而对于有效载荷为其他类型的 Packet-In 消息,链路发现管理模块会进一步将它们交给拓扑管理模块处理,该模块的主要作用是根据已经发现的链路信息计算出一个拓扑实例以储存网络的拓扑信息,而后进行各交换机之间路径的计算。
接着就进入到设备管理模块,该模块是根据 Packet-In 消息包含的源 MAC 地址识别网络设备的信息并记录。
之后, 便是对该消息进行负载均衡以及防火墙策略的验证,如验证成功则经转发模块正常转发,否则,直接泛洪该数据包。
Floodlight 实现了对两种链路的发现:
1、纯 SDN 环境下连接在 OpenFlow 交换机之间的内部(Internal)链路
2、在混合网络场景下跨越非 OpenFlow 区域的外部(External)链路。
与大多数控制器一样,Floodlight 的链路发现采用的是 OpenFlow 发现协议, 它利用 LLDP 使得网络设备可以向邻居设备通告其主要功能以及设备信息。如图10 所示,LLDP 数据包的结构包括数据包头部和链路层发现协议数据单元两个部分。
数据包头部又包括 Dst MAC、Src MAC、Ether Type 三个字段,其中 Dst MAC 采用多播地址 01:80:C2:00:00:0E,Src MAC 被设置为各交换机出端口的硬件地址,而 Ether Type 恒为 0x88CC。LLDPDU 由许多 TLV 结构组成,其中 Chassis ID、 Port ID以及TTL是三个必选的TLV,其后是多个可选TLV(例如DPID、Timestamp 等)和一个 LLDPDU TLV 的结尾标识。
Floodlight 中的链路是有向的,一般情况下连接在两个 OpenFlow 交换机之间的是双向对称的内部链路。接下来以图 11 来说明 Floodlight 在两个 OpenFlow 交换机之间发现一条单向内部链路的过程。
①首先 Floodlight 为 OpenFlow 交换机 A 的 P1 端口构建一个独特的 LLDP 数据包,独特体现在交换机标识字段和端口标识字段分别设为交换机的 DPID 和 P1 的端口号,Src MAC 设置为 P1 端口的硬件地址。
②LLDP 数据包被封装在 Packet-Out 消息中,然后下发至交换机 A,并且指定行动从 P1 端口发送出去。
③当它抵达 OpenFlow 交换机 B 的 P1 端口后,由于没有匹配的流表项,会被封装在 Packet-In 消息中上交给 Floodlight 进行处理。
④Floodlight 通过分析该 Packet-In 消息中包含的 LLDP 数据包,比对后发现该数据包与自己为 OpenFlow 交换机 A 的 P1 端口所构建的 LLDP 数据包一致, 于是得出结论存在一条从交换机 A 的 P1 端口到交换机 B 的 P1 端口的单向内部 链路(如图中实线所示)。
此外,一旦推测出了一条单向内部链路,Floodlight 会立刻发送反向 LLDP 数据包给 OpenFlow 交换机 B 的 P1 端口,以类似的方法推断是否具有从交换机 B 的 P1 端口到交换机 A 的 P1 端口的反向内部链路。
为了检测跨越非 OpenFlow 区域的外部链路,Floodlight 使用的是 BDDP 数 据包来执行该过程。特别地,BDDP 数据包是 LLDP 数据包的广播版本,使用广播地址作为其目的 MAC 地址。
实际上,外部链路的发现过程在 Floodlight 中是作为内部链路的发现过程的补充,我们以图 12 来说明 Floodlight 发现一条外部 链路的过程。
①Floodlight 首先会为 OpenFlow 交换机 A 的 P1 端口构建一个 LLDP 包来执 行正常的内部链路发现,但是由于具有多播目的 MAC 地址的 LLDP 数据包被转发到传统交换机 C 的 P1 端口后会被丢弃。因此,Floodlight 后续无法再收到该LLDP 数据包。
②Floodlight 会继续为 OpenFlow 交换机 A 的 P1 端口构建一个 BDDP 数据包 并以 Packet-Out 消息的形式下发,而具有广播目的 MAC 地址的 BDDP 数据包能 够透明地穿过传统转发设备,因此当它到达传统交换机 C 后可以被其正常转发 给 OpenFlow 交换机 B 的 P1 端口。
③类似的,OpenFlow 交换机 B 会将收到的 BDDP 数据包封装在 Packet-In 消息中上传给 Floodlight。
④Floodlight 通过分析该 Packet-In 消息中包含的 BDDP 数据包,发现与自己 为 OpenFlow 交换机 A 的 P1 端口所构建的 BDDP 数据包一致,于是得出结论从 交换机 A 的 P1 端口到交换机 B 的 P1 端口具有单向的外部链路。
需要注意的是,Floodlight 在推测出了一条单向外部链路后会直接创建一条 反向的外部链路,而不需要重新发送反向 BDDP 数据包来推断是否存在反向外 部链路。此外,如果 Floodlight 在先后为某端口构建了 LLDP 数据包和 BDDP 数 据包后,后续两种类型的数据包都没有被收到,则会认为该端口是一个边界交换 机端口,即连接主机的端口。以上两种类型的链路发现过程定期每 15 秒执行一 次以捕获网络链路信息的动态变化。
拓扑管理工作在链路发现管理之后,主要负责监视链路发现过程中是否出现了网络拓扑状态发生变化的事件,例如交换机的增加或删除、交换机端口的激活或关闭以及 链路的时延状态发生了变化等。
一旦网络中出现了这样的拓扑更新事件,拓扑管理机制会立刻重新计算一个最新的拓扑实例(Topology Instance)。计算拓扑实例的目的是对当前时刻网络拓扑状态的静态捕捉,以保存当前时刻网络的完整拓扑信息,而网络中的其他依赖于拓扑信息的服务其本质是依赖于最新时刻所计算出的拓扑实例。
在计算一个拓扑实例时,主要可分为五个关键步骤,具体如图 13 所示。
第一步是识别交换机集群(Cluster),交换机集群在 Floodlight 中被定义为一组 相互连通的交换机集合。
第二步,Floodlight 会识别各集群内部交换机之间相连 的链路。
第三步,将第一步所识别出的交换机集群使用第二步所识别的链路合并 成交换机群岛(Archipelago),群岛被定义为单个或多个交换机集群的集合。
第四步,以群岛为基本单位,利用最短路径算法分别在每个群岛内部的两两交换机 之间默认计算三条最优路径,并将计算出的路径保存到路由缓存中,便于转发时提取。
第五步,分别计算每个群岛的广播端口,广播端口是指群岛内部所有可以对数据包进行正常广播的交换机端口的集合。
值得注意的是,Floodlight 之所以引入交换机集群和交换机群岛的概念,其 一是有利于节约路由计算过程的存储开销,其二是为了提高计算的效率。
简单来说,它将路由计算限制在同一群岛内部的交换机之间进行,而位于不同群岛的交换机之间无需计算路由。如果没有采用这种机制,那么整个网络中任意两两交换机之间也都需要进行路由计算,并且还需要存储两两交换机之间的多条路径。当网络规模变大时,Floodlight 控制器的存储开销会显著增大,路由计算的效率也会大大降低。
字节(Byte): 一个8位无符号数。
包(Packet): 一个以太网帧,包括报头和有效载荷。
端口(Port): 数据包进入和退出OpenFlow管道。可以是物理端口、交换机定义的逻辑端口或OpenFlow协议定义的保留端口。
管道(Pipeline): 在OpenFlow交换机中提供匹配、转发和包修改的一组链接流表。
流表(Flow Table): 一个阶段的管道。它包含流条目。
流条目(Flow Entry): 流表中用于匹配和处理数据包的元素。它包含一组匹配信息包的匹配字段、一个匹配优先级、一组跟踪信息包的计数器和一组要应用的指令。
匹配字段(Match Field): 数据包与之匹配的字段,包括信息包头、入口端口和元数据值。匹配字段可以使用通配符(匹配任何值),在某些情况下可以使用位掩码。
元数据(Metadata):一个可屏蔽的寄存器值,用于将信息从一个表传递到下一个表。
指令(Instruction):说明附加到一个流条目和描述OpenFlow处理,当一个数据包匹配流条目。指令要么修改管道处理,比如将数据包定向到另一个流表,要么包含一组要添加到操作集的操作,要么包含一组要立即应用到数据包的操作。
行动(Action):一个操作,将数据包转发到一个端口或修改包,如递减TTL字段。可以将操作指定为与流条目相关联的指令集的一部分,或者指定为与组条目相关联的操作桶的一部分。操作可以累积在信息包的操作集中,也可以立即应用到信息包。
行动组(Action Set):一组与包相关的行为,处理每个表和执行指令集指示数据包退出处理管道。
组(Group):一组动作的Bucket和一些手段选择的一个或多个这些Bucket在每个包的基础上应用。
行动桶(Action Bucket):一组行为和相关参数,定义组。
标记(Tag):一个头可以插入或删除从一个数据包通过推动和流的行为。
外层标签(Outermost Tag):标签出现接近一个数据包的开始。
控制器(Controller):一个实体与OpenFlow开关使用OpenFlow协议交互。
计(Meter):一个交换机元件,可以测量和控制数据包的速率。如果通过该仪表的包率或字节率超过预定义的阈值,该仪表触发一个仪表频带。如果Meter丢失了数据包,它被称为速率限制器。