杨晓,刘琦
(西华大学计算机与软件工程学院,成都 610039)
人类社会已经进入网络无所不在的信息时代,截至2017年3月,全球互联网用户突破37.4亿,全球每人平均每月的网络流量也将于2021年达到61GB(从2016年的24GB)。互联网能够快速发展主要得益于它优良的体系结构和网络技术,然而伴随着推广的深入和网络规模的不断扩大,爆炸式的增长使其自身结构的僵化问题越来越明显,互联网原有的结构反而成为阻碍它进一步发展的最大障碍。
SDN(软件定义网络)是一种新式的网络架构,这种方式给了可以破除当前网络架构存在的瓶颈的希望。在传统的网络结构中,控制平面和数据平面是整合在同一个网络设备中,而SDN的一个核心点就是通过打破垂直整合,将网络的控制逻辑从底层的路由器和交换机中分离出来,促进网络控制(逻辑)中心化,引入对网络可编程的能力[1]。网络策略的制定、交换硬件中的执行以及流量的转发之间的分离,这是我们所期望灵活性的关键之处。通过将网络控制问题分离成一些易于解决的小部分,SDN使得在网络中易于创造和引入新的抽象,这样简化了网络管理,有利于网络革新和发展。另外,在传中的IP网络中所有的转发行为都是基于单一的IP地址进行转发,而在SDN中,所有转发都是基于流(一套基于数据包头域的规则)进行转发,这种细粒度的方式更加方便于策略的实现[2]。
IEEE 802.3ax标准的 LACP(Link Aggregation Con⁃trol Protocol,链路聚合控制协议)是一个关于动态链路聚合的协议,它通过协议报文LACPDU(Link Aggrega⁃tion Control Protocol Data Unit,链路聚合控制协议数据单元)和相连的设备交互信息[3]。当端口启用LACP协议后,端口通过发送LACPDU来通告自己的系统优先级、系统MAC、端口的优先级、端口号和操作key等[4]。相连设备收到该报文后,根据所存储的其他端口的信息,选择端口进行相应的聚合操作,从而可以使双方在端口退出或者加入聚合组上达到一致。在传统网络中的交换设备,一般存在多个以太网口,同时在大型网络中也可能会存在单点链路带宽瓶颈,例如Web服务器,同一时间可能会有上千万的访问量,单个接口无法满足这么大的吞吐量。LACP可以利用这些接口聚合为一个更大带宽的逻辑接口,同时可以实现链路的容错性,当聚合端口中的一条或几条链路故障,仍能保证链路的连通性。
如何将传统网络架构迁移至新的软件定义网络架构中去,一直是近些年来讨论研究的热点。本文就尝试探索如何传统的网络架构中的链路聚合迁移至新的软件定义网络架构中。本文通过SDN方式基于Ryu控制器(SDN开源控制器)研究和实现LACP功能,使得LACP协议可以在软件定义网络环境中实现。
依据IEEE的802.1ax协议标准并基于Ryu控制器平台,设计交换模块、LACP解析与封装模块、LACP处理逻辑模块。
本系统是基于Ryu控制器的,Ryu控制器是基于事件机制的,每个OpenFlow消息在进入到Ryu控制器后,都会被封装成一个事件;每个应用在加载时,主动向Ryu控制器注册在某个通信阶段,自己期望的处理事件。
本系统注册事件列表如下:
● ofp_event.EventOFPSwitchFeatures,CONFIG_DISPATCHER
●lacplib.EventPacketIn,MAIN_DISPATCHER
●lacplib.EventSlaveStateChanged,MAIN_DISPATCHER
●ofp_event.EventOFPPacketIn,MAIN_DISPATCH⁃ER
●ofp_event.EventOFPFlowRemoved,MAIN_DISPATCHER
在Ryu控制器中,通信阶段分为以下四个:
●HANDSHAKE_DISPATCHER:连接建立阶段,交换Hello信息
●CONFIG_DISPATCHER:等待接收交换机特性阶段
●MAIN_DISPATCHER:正常通信阶段
●DEAD_DISPATCHER:连接断开阶段
程序可以指定在某个阶段,来处理相应的事件,当在其他非指定阶段出现注册事件,则不会触发相应方法执行。
当相应的OpenFlow消息到达Ryu控制器,控制器的事件调度器会根据应用的注册的事件类型,来调用对应的方法,对事件进行处理。
本系统分为LACP解析与封装模块,LACP处理逻辑模块、交换模块。模块之间彼此独立,通过Ryu事件调度器,完成彼此之间的协作。LACP处理模块位于Ryu事件处理中最顶层,最原始的packet-in数据包首先会触发它的处理,以执行与LACP相关的功能;在对原始的pack-in事件进行过滤后,将不包含LACP信息的packet-in事件重新发回到Ryu控制器系统中,以触发交换模块处理。在LACP处理逻辑模块中,会使用LACP解析封装模块,来将原始的字节流转换为可以处理的信息,同时将处理的结果序列化为可以在网络中传输的LACP协议数据包字节流。而交换模块则单纯处理与MAC寻址相关的功能。LACP处理逻辑模块和交换模块彼此之间是解耦,它们之间的通过Ryu控制器进行协作。事件之间关系如图1所示。
图1 事件逻辑
作为交换模块,主要实现学习MAC地址,并根据学习到的信息进行数据包的转发,当有端口的LACP状态变化的事件时,清理与LACP端口相关的流表信息。因为,为了实现LACP功能,控制器是通过流表来控制交换机的转发行为,所以当相应接口失效,或者接口重新加入聚合组,需要清空与之相关的流表,重新建立新的转发方式。交换模块处理逻辑如图2。
交换模块注册对以下三个事件监听入口:
●ofp_event.EventOFPSwitchFeatures
●lacplib.EventPacketIn
●lacplib.EventSlaveStateChanged
事件ofp_event.EventOFPSwitchFeatures会在连接建立阶段,完成对tablemiss流表添加,以完成MAC地址的学习。事件lacplib.EventPacketIn会在正常通信阶段,处理经过LACP模块过滤后的packet-in事件,这些事件经过过滤后,所有的packet-in事件只会与数据包的交换有关,屏蔽的与LACP的联系,减少了LACP模块与交换模块之间的耦合性。事件lacplib.Event⁃SlaveStateChanged会在正常通信阶段,处理交换机中端口状态变化(从非LACP状态到LACP状态,或LACP状态失效),完成对交换机内的流表清理初始化工作。
图2 交换模块处理逻辑
由于在网络中传输的LACP数据包都是字节流,无法直接处理,所以根据IEEE 802.1ax协议标准,并借助程序开发语言Python中的struct模块来设计解析与封装模块,将原始LACP字节流的解析成可以处理的信息,以及将处理好的数据封装为可以在网络中传输的字节流。此模块用于协助LACP模块对协议的处理。
在解析数据包时,当LACP模块调用本模块解析协议的原始数据时,会调用struct模块中的struct.un⁃pack_from,根据LACP协议字段值顺序以及大小,以偏移量作为参数将原始的字节流解码为可以处理的信息。主要解析的关键字表1所示。同样在封装数据包,使用struct模块中的pack方法,根据LACP协议字段顺序进行组装,得到一个可以直接发送的网络数据包。
表1 LACP协议关键字段值
作为在Ryu平台实现链路聚合控制协议,主要是通过控制actor_state字段值,来与对端交互。本系统主要就是根据此字段值来实现链路的聚合。actor_state为一字节,8个比特位,每个位对应的含义如表2。
●LACP_Activity:标志LACP活动状态,主动为1,被动为0。
●LACP_Timeout:标志链路超时时间控制值,Short Timeout为 1,Long Timeout为 0。
●Aggregation:如果标志值为1,则系统认为这个链路为可聚合;如果为0,则这个链路为独立的。
●Synchronization:如果值为1,系统认为这个链路是IN_SYNC状态,即这个链路已经分配给合适的链路聚合组,这个组已经与兼容的链路聚合相关联;为0表示为OUT_OF_SYNC,表示该链路未在聚合态。
●Collecting:如果值为1,在这条链路聚集传入的帧为enabled状态,即在没有管理性更改,或接收消息更该的情况下,不会被禁用;否则为0。
●Distributing:如果值为0,在这条链路上分发传出的帧为enabled状态,即 在没有管理性更改,或接收消息更该的情况下不会被禁用;否则为0。
●Defaulted:如果值为1,标志表示本端的接收计算机正在使用默认的运行对端信息,这些信息是为对端管理配置的;如果为0,已在LACPDU中收到正在使用的运行对端信息。
●Expired:如果值为1,表示本端的接收机是过期状态;如果为0,本端接收机为过期。
当有关于LACP的packet-in事件触发时,Ryu控制器会调用这个模块进行处理。处理逻辑关系见图3。同时控制器中维护一个绑定信息状态变量bond,以记录不同交换机不同端口LACP状态信息(是否启用LACP,超时时间)。
首先根据事件中的信息,在bond中查看接收此LACP数据包的交换机端口的状态,来判定这个端口是否启用了LACP;若对应端口未启用LACP,则将此接口启用,并向 Ryu控制器发送 lacplib.EventSlaveStat⁃eChanged事件,以通告端口的状态改变。
表2 actor_state控制字段
接着,依据数据包中的LACP超时时间类型为SHORT_TIMEOUT_TIME或者 LONG_TIMEOUT_TIME,来设置流表的超时时间。因为作为被动端,交换机会根据流表的超时时间自动调整端口的状态。当流表的超时时间达到,但仍未收到主动端的LACP数据包,以更新超时计时器,则表示LACP超时时间到达,交换机会主动删除这条超时的流表,并向控制器发送ofp_event.EventOFPFlowRemoved流表移除消息,在控制器收到此条消息会主动更新控制器中保存的绑定信息,并清除交换机内与该端口相关的LACP流表信息。以此,来自动完成与主动端链路状态保持。
然后,根据LACP超时时间,来判断超时时间是否变化,如果变化需要修改控制器中保存的绑定状态信息,并下发指令,修改交换机内相应LACP流表的超时时间。
最后,作为对packet-in消息回复,构造响应LACP数据包,通过packet-out消息发送响应信息给主动端,以完成和主动端的交互。
图3 LACP处理逻辑
LACP模块包含的关键方法:
●do_lacp:LACP 处理
●_create_response:创建回应数据包,并序列化
●_create_lacp:构造LACP响应数据包
●_get_slave_enabled:获取端口的LACP状态
●_set_slave_enabled:设置LACP状态
●_get_slave_timeout:获取端口的超时时间信息
●_set_slave_timeout:设置端口的超时时间信息
本实验通过仿真工具Mininet构建一个具有一个OpenFlow交换机,四台主机网络,其中主机h1与交换机之间有两条网络连接线。如图4所示。
图4 实验拓扑
完成后,如图5看到逻辑接口bond0为MASTER,物理接口h1-eth0和h1-eth1为SLAVE。
图5 h1最终配置结果
执行程序,在终端中有一下信息输出,如图6。可以看出LACP起用,被动端的接口也已经UP,timeout事件从默认的0秒变为LONG_TIMEOUT_TIME,即90秒。lacp的响应数据包被发送出去。在最后输出信息:“slave state changed port:2 enabled:True”表示应用接收到了EventSlaveStateChanged事件。
图6 程序执行输出
控制器端的输出如图7。
图7 控制器终端输入信息
检查流表,如图8,可以看出:在当LACP数据包(类型为0x8809)从h1的eth1接口被发送(进入端口为 s1-eth2,mac 地址为 00:00:00:00:00:12),packet-in消息被发送;在当lacp数据包从h1的eth0接口被发送出去时,packet-in消息被发送出去;同时还包含一条table-miss流表项。
图8 流表信息
首先验证链路可以改进链接速度,将去往h1的流量分布到两个链路上。
首先执行,h2 ping h1如图9。
图9
当继续发送ping,检查OpenFlow交换机的流表信息,如图10,相比刚开始,添加了两条流表项。从这可以看出,S1-eth 1被用于h2和h1的通信。
图10
接着从h3 ping h1,结果如图11。
图11
在OpenFlow交换机中可以看到如图12,可以看出又添加了两条流表项,但是参数duration的值比较小。由此可以得知,交换机的eth 2接口用于h3和h1通信。
图12
同样在从h4到h1执行ping测试。可以得到如表3的端口使用表。
表3
由此得出,两条链路都为H1通信服务。链路聚聚合用成功。
验证可以实现,数据链路的容错性。当前状态是,当从h2和h4与h1通信,交换机的端口eth 2被使用,当从h3与h1通信,eth1被使用。将交换机的eth 1从聚合链路中移除。由于H1的eth 0停止,h3与h1无法通过ping测试,当经过90秒后,新的消息日志会出现,如图13。
图13
可以看出超时时间到达,断开的接口的所有学习的MAC地址和流表项都会删除,回到初始状态。如果有新的通信活动在h1和h3之间,存在的聚合链路会学习新的MAC地址,注册新的流表项。如图14。
图14
之前的无法ping测试,现在恢复,如图15。
图15
由此可以看出,即使某些链路出现问题,仍然能够实现通信,实现了容错性。
本文根据OpenFlow协议,以及链路聚合控制协议LACP,在基于Ryu框架中,探索如何将链路聚合在软件定义网络环境中实现。从本实验可以看出软件定义网络的优势:不用接触底层设备,可以用过中心控制器来管控网络,为网络管理带来便利性;快捷的部署,对于新的技术协议,在传统的环境中去验证十分困难,但在SDN环境中,屏蔽底层细节,通过统一的流表样式来控制交换机的数据包转发行为,为以后的网络发展与技术革新带来新的动力。本设计在一定程度上实现了链路聚合控制协议,但并未实现主动式的,交换机只作为一种被动式角色。今后的研究可以尝试,设计一套完整的LACP协议的实现。