链路聚合在PTN智能接入终端上的设计与实现
2013-01-31熊志明肖萍萍
熊志明,肖萍萍
(武汉邮电科学研究院光纤通信技术和网络国家重点实验室,湖北 武汉430074)
网络技术的不断发展使得网络传输的数据量急剧增加,网络的带宽资源显得越来越宝贵,如何有效提高带宽并能适应目前传输网络成为讨论的关键。解决这一问题最直接的方法就是提高网络传输的链接能力。要增加网络的链接能力,通常有两种选择:一是提升本地链接能力(即硬件升级),二是使用链路聚合来聚合两个或两个以上的低速链接。当然,通过硬件升级把旧网络升级成新网络来提高网络带宽无疑是最直接的解决办法,但通过这样的方法要花费大量的时间和金钱,对于用户来说并不可取,同时这种方案不够灵活。随着每一次硬件升级都要更换新的产品,造成极大的资源浪费,这不是运营商希望看到的结果。为了更好地解决这个问题,链路聚合(Link Aggregation)技术应运而生,链路聚合是指将多个端口汇聚在一起形成一个汇聚组,以实现出/入负荷在汇聚组中各个成员端口中的负载分担,同时也提供了更高的连接可靠性,灵活有效地提高带宽。早期的链路聚合技术没有实现标准统一,各个厂商有各自私有的解决方案,实现功能不尽相同,各设备间也很难相互兼容。为此,IEEE制定了链路聚合的标准,目前以IEEE 802.3ad为正式标准,LACP是该标准的主要内容之一,是一种实现链路动态汇聚和解汇聚的协议。
1 LACP的原理
LACP协议聚合的两端,即本端(Actor)和对端(Partner)通过LACPDU报文的交互来获取双方的各种聚合信息,从而通过链路汇聚控制协议数据单元(Link Aggregation Control Protocol Data Unit,LACPDU)实现动态链路汇聚和解汇聚。将某端口的LACP协议使能后,该端口将通过发送LACPDU协议报文通告对端自己的状态信息,包括各种优先级等。对端将接收到的信息与其他端口所保存的状态信息进行对比,并按照一定的算法(一般为hash算法)对链路汇聚的端口进行相应的选择,从而双方对端口加入或退出某个动态汇聚组进行协商达成一致。由于LACPDU协议报文的交互是周期性的,即聚合的双方每隔一段时间(由系统设定)便互发一次LACPDU协议报文,所以当使能端口成员链路因为某种原因不能工作时,链路会对此很快感知,并重设链路端口状态,置该链路为阻塞,流量被重分配给其他使能端口成员链路。这样就实现了带宽增加、链路动态备份的功能,从而提高了链路的可靠性。
2 链路聚合的实现
在研的PTN智能接入终端是一个具有4个百兆口、2个千兆口的适用于PTN传输网的智能接入终端。本设计动态链路聚合基于该设备来实现。动态链路聚合通过事件来驱动,每个事件发生的时序都是随机的,为了更好地控制在不同状态产生的不同事件都能够有正确合理的处理,有限状态机是最为有效的方法。
2.1 状态机模块总体框架
链路聚合的实现的状态机总体框架如图1所示。
图1 链路聚合总体框架图
1)接收状态机模块(Rx状态机)
处理从对端收到的LACP协议报文。主要包括报文解析;记录对端聚合的相关信息;设置端口选择状态(选中/未选中);根据对端信息,设置链路聚合的相关数据;处理本端保存的对端聚合相关的数据老化。
2)周期发送状态机(PTx状态机)
周期发送定时机制的建立,是为了让本端和远端交互周期的LACPDU报文来维护链路的聚合,同时确定并控制这些周期性传输产生的频率。本端或对端任一方的需要都会产生周期的发送。而发送的速率由对端确定,该速率与其定义信息接收的超时时间相关。
此状态机包含4个状态:
(1)NO_PERIODIC(无周期),在此状态不能周期性地发送。
(2)FAST_PERIODIC(快速周期),在此状态以快速率使能周期性地发送。
(3)SLOW_PERIODIC(慢速周期),在此状态以慢速率使能周期性地发送。
(4)PERIODIC_TX(周期发送),此状态是一个瞬态,进入周期计时终止,当插入NTT标位时就转入快速周期或者慢速周期,慢速周期或者快速周期由对端的LACP超时设定决定。
是否发生周期性发送由本端和对端的被操作端口状态决定。端口状态分为LACP激励状态和LACP消极状态。在两端至少有一端端口状态为LACP激励状态时就产生周期性发送,两端同时设置为LACP消极状态时就不会产生周期性发送事件。类似的,如果两端的端口使能或者LACP使能变量设置为无效时,表明端口的LACP协议功能未使能,或者端口不可用,此时周期性发送事件不会发生。
如果发生了周期性发送事件,那么其发送周期速率由对端被操作的端口状态LACP超时变量决定。如果该变量为短超时,那么周期性发送的内部时间将用快速发送周期。反之内部时间将用慢速发送周期。本设计中慢速周期发送定时器的周期设置为30 000 ms,快速周期发送定时器的周期设置为1 000 ms。
3)多路转发状态机(MUX状态机)
MUX状态机是用来根据本端和对端的选中状态,通过控制端口阻塞与否来控制接收和发送数据功能的开启和关闭。状态控制又可以分为独立控制和耦合控制。独立控制是指端口的接收和发送功能是可独立控制,即可异步控制,一个功能开启,另一个功能关闭,如端口使能或去使能及端口的数据帧发送。耦合控制是指端口的接收和发送只能同时开启或关闭。本次设计中为了使事件响应更快、处理更简化,采用耦合控制。
4)发送状态机模块(Tx状态机)
它完成对LACP协议报文内容的填充,并处理协议报文的发送,当收到各种标志通知时,立即调用报文发送模块发送报文。当周期状态机状态为NO_PERIODIC(无周期)时,不交互LACPDU报文,同时将标志位NTT(Need To Transmit)置为无效;当LACP使能变量有效且标志位NTT有效时,又由于LACP协议属于慢速协议,每秒最多允许发送10个LACP协议报文,LACPDU报文的发送将严格遵循这一原则。为确保遵循这个要求,状态机设置内部维护NTT标志和一个全局变量来记录已发送协议报文的数目,每隔1 s就将这些参数清零。
5)逻辑选择器
设置端口的选中状态,配合其他状态机完成聚合功能。
图1说明了这些状态机之间的关系以及它们之间的信息交互。标记了Partner状态信息的这组箭头代表新Partner的信息,包含在一个传入的LACPDU或是系统提供的默认值中,通过接收状态机反馈给各个状态机。标记了Actor状态信息的这组箭头代表状态机之间更新的Actor状态信息数据。LACPDUs的传输是由于周期性状态机触发产生一个周期性的LACPDU或需要传达给Partner的Actor的状态信息改变产生的。LACPDU的传输要通过置标志位NTT。剩下的箭头标记代表在状态机中描述全局变量,允许触发一个状态机的事件发生在另一个状态机。
2.2 状态机的软件实现
软件实现状态机通常有内嵌switch、状态表、用函数指针作为状态,用函数地址代替状态值,每个状态对应于一个函数指针。
本次LACP状态机的软件实现借鉴了以上3种方法,用枚举值表示状态,用函数指针的方式实现状态的动作和转换。端口对应的本端和对端的聚合相关信息保存在结构体指针全局变量lacp_info_t指向的内存中。代码框架具体如下:
/*lacp事件状态枚举*/
typedef enum/*lacp_event_t*/
{
Lac_null=0,
Lac_init,/*lacp协议初始化*/
Lac_tick,/*定时器计时时间戳*/
Lac_port_enabled, Lac_port_disabled,/*端口lacp协议功能使能和去使能*/
Lac_new_info,
Lac_attach, Lac_attached,/*端口lacp添加和已添加*/
Lac_detach, Lac_detached,/*端口lacp分离和已分离*/
Lac_enable_collector, Lac_collector_on,/*逻辑选择器使能和打开*/
Lac_disable_collector,Lac_collector_off,/*逻辑选择器去使能和关闭*/
Lac_enable_distributor,Lac_distributor_on,/*适配器使能和打开*/
Lac_disable_distributor,Lac_distributor_off,/*适配器器去使能和关闭*/
Lac_ntt, Lac_txd,/*lacp协议报文发送标志和报文发送*/
Lac_check_moved,/*确认端口分离*/
}lacp_event_t;
/*接收状态机函数*/
void rx_machine(lacp_port_t*port,lacp_event_t event,lacp_pdu_t*pdu)
{switch(事件)
{
如果事件=Lac_check_moved:通过判断端口状态是否继续初始化;
如果事件=Lac_init:初始化接收端口;
如果事件=Lac_port_disabled:去使能接收端口;
如果事件=Lac_port_enabled:通过判断端口使能及协议使能做相应处理;
如果事件=Lac_tick:通过时间戳判断是否将本端加入聚合组;
如果事件=Lac_received:通过时间戳判断是否将对端加入聚合组;
}
};
/*发送状态机函数*/
void tx_machine(lacp_port_t*port,lacp_event_t event)
{switch(事件)
{
如果事件=Lac_init,Lac_port_disabled:停止计时;
如果事件=Lac_ntt:开启lacp协议内部计时器;
如果事件=Lac_tick:开启周期计时;
如果事件=Lac_txd:通过条件判断发送协议报文或者开启周期计时;
}
};
/*周期状态机函数*/
void per_machine(lacp_port_t*port,lacp_event_t event)
{switch(事件)
{
如果事件=Lac_init,Lac_port_disabled:周期计时设置为停止;;
如果事件=Lac_tick:通过判断周期是否超时,进入报文发送状态机或停止周期计时;
}
};
/*多路转发状态机函数*/
void mux_control(lacp_port_t*port,lacp_event_t event);
{switch(事件)
{
如果事件=Lac_init:初始化端口lacp状态;
如果事件=Lac_tick:通过时间戳判断是否加入聚合组;
如果事件=Lac_new_info:是否改变聚合端口;
如果事件=Lac_distributor_on:不做处理;
如果事件=Lac_distributor_off:停止分配,进入发送状态机处理;
如果事件=Lac_collector_on:开启逻辑选择器,进入发送状态机处理;
如果事件=Lac_collector_off:不做处理;
如果事件=Lac_received:通过时间戳判断是否将对端加入聚合组;
}
};
/*逻辑选择状态机函数*/
void hw_control(lacp_port_t*port,lacp_event_t event);
switch(事件)
{
如果事件=Lac_init:不做处理;
如果事件=Lac_attach:将多路选择器状态设置为协议端口已关联;
如果事件=Lac_detach:将多路选择器状态设置为协议端口未关联;
如果事件=Lac_enable_collector:接收使能,备份端口数据,开启接收状态函数,开启逻辑选择器;
如果事件=Lac_disable_collector:接收去使能,备份端口数据,开启接收状态函数,关闭逻辑选择器;
如果事件=Lac_enable_distributor:发送使能,备份端口数据,开启发送状态函数,开启逻辑适配器;
如果事件=Lac_disable_distributor:发送去使能,备份端口数据,关闭发送状态函数,关闭逻辑适配器;
}
}
3 测试及结论
PTN智能接入终端PAS是公司研发的一款承载PTN传输网的接入设备。本次测试设备的硬件设计具有2个GE口,4个电口,支持动态链路聚合。如图2搭建测试环境,正确连接各物理链路,确保各相关端口的状态为up状态。
图2 测试环境
测试步骤:
1)将PAS接入终端的FE1/0/1,FE1/0/2,FE1/0/3,FE1/0/4端口LACP使能;与交换机的4个端口相连并使能端口LACP。
2)以太网测试仪的千兆端口连接PAS接入终端的GE口。
3)以太网测试仪与PAS接入终端相连的端口A源MAC设置为00-00-0F-00-FF-00,与交换机相连端口B源MAC设置为00-00-0F-00-00-AA,从A发送目的MAC为00-00-0F-00-00-AA的连续报文2 000 000个。
4)用命令display interface查看端口的收包数目如表1所示。
5)人为制造链路故障,如将PAS接入终端的FE1/0/4端口断纤,用display interface查看端口收包数目如表2所示。
表1 端口收包数目1
表2 端口收包数目2
结果分析:根据hash算法算出的hash值为0~7,然后根据负载分担表将流量分配到各个端口,理论分析的结果与实际结果一致。本方案在该设备上实现了动态链路聚合,无需手动配置,只需使能端口的LACP协议功能,聚合接口的建立、成员接口的加入、活动接口的选择完全由LACP协议通过协商完成链路的聚合操作。
[1]IEEE Std 802.3ad,Amendment to carrier sense multiple access with collision detection(CSMA/CD)access method and physical layer specifications—aggregation of multiple link segments[S].2000.
[2]郑涛,郭裕顺.基于LACP协议的链路聚合状态机模块的实现[J].计算机系统应用,2010,19(5):104-108.
[3]池元武.用状态机原理进行软件设计[EB/OL].[2011-08-20].http://www.docin.com/p-26276442.html.
[4]李泽杰.面向流媒体传输的链路聚合技术的研究与实现[D].广州:广东工业大学,2008.