共7条
1/1 1 跳转至页
2002年嵌入式大会论文集,发现有一边文章有意思!
VxWorks系统中MPLS的实现
朱巍 陈剑 王海
(解放军理工大学通信工程学院交换技术与ATM研究中心 南京 210007)
Email: zw84611@sina.com 电话:025-13813802434
摘要:多协议标记交换(MPLS)技术是当前的一项热点网络技术,该技术将第三层路由与第二层交换相结合,兼有两者的长处,被业界认为是当今数据网络领域内最有前途的网络解决方案之一。本文讨论了在嵌入式实时操作系统VxWroks中MPLS关键技术的实现,主要内容包括标记转发、标记分发协议和标记管理模块等。
关键词:VxWorks , 多协议标记交换, 标记分布协议
Implement MPLS in VxWroks
Abstract: MPLS ( Multiprotocol Label Switching ) is a popular network technology. It combines the advantage of lay 3 routing and lay 2 switching . And it is regarded as one of the core network technologies in the future. In this article we implement MPLS in VxWorks, which is real time operating system. The key technology includes label forwarding, label distribution protocol and label management module etc.
Key word: VxWorks, MPLS, Label Distribution Protocol
1. MPLS简介
多协议标记交换(MPLS)技术是当前的一项热点网络技术,该技术将第三层路由与第二层交换相结合,兼有两者的长处,并广泛支持以太网、PPP、ATM、帧中继、FDDI等多种链路层协议。MPLS在VPN、流量工程、QoS方面都有着独到的优势,被业界认为是当今数据网络领域内最有前途的网络解决方案之一。
MPLS的主要工作原理是将较为复杂的选路工作放在网络边缘进行,而在网络核心部分实现简单的交换。MPLS使用一个定长的、短的标记(label)来简化数据转发过程。它通过标记边缘路由器LER(Label Edge Router)处生成转发等价类FEC(Forwarding Equivalence Class),为每个MPLS分组分配一个标记。在MPLS域内的LSR(Label Switching Router)对收到的MPLS分组进行标记交换。标记的请求、分发和保持由标记分发协议LDP(Label Distributing Protocol)来完成。这样可将网络层的数据分组交换转换到链路层来实现,使网络既能充分利用网络层路由选择的灵活性又能充分发挥链路层的效率和优势。从而使网络具有良好的可扩展性和QOS保证能力。
MPLS的核心组件包括转发和控制两大模块。其转发模块用来实现MPLS封装、标记匹配算法和数据包的转发。控制模块用来实现路由信息的一致分布,并根据路由信息建立和维护转发表。由于MPLS的标记头比典型的IP头要简单,因此MPLS实现转发比IP要简单,速度更快,也更容易用硬件实现。MPLS的控制模块使其能够支持显式路由、QoS、VPN和流量工程,这也使得MPLS拥有广泛的应用前景。
2. VxWorks操作系统简介
VxWorks操作系统是WindRiver公司开发的一种高性能的嵌入式实时操作系统。它带有一个功能强大的集成开发环境Tornado。VxWorks具有软件生成代码小、实时性强及响应速度快等特点,特别适合于具有实时和多任务要求的系统,因此广泛应用于通信产品开发中。VxWorks内建与BSD4.4兼容的实时TCP/IP协议栈,适用于从高性能网络交换设备到低价的网络接入设备,如10M/100M以太网交换机、广域网接入设备、ATM交换机等。
3. MPLS在VxWorks系统中的实现
MPLS的实现可以分为转发和控制两大模块。其基本结构如图3-1所示。
图1 MPLS模块结构
3.1 MPLS转发模块的实现
本文中讨论的转发模块便是在以太网中实现的。在不同的数据链路层之上实现MPLS转发模块有一定区别。在ATM或帧中继这样的技术中,标记可以作为其链路层头的一部分携带。而在以太网、FDDI、PPP等技术中,链路层头无法携带标记信息。在这种情况下,标记被置于链路层和网络层首部之间的“填充片”(Shim)中。
每个标记的封装格式如图3-3所示。其中Label(标记值)20比特,Exp(实验保留位)3比特,S(标记栈栈底标志)1比特,TTL(生存期)8比特。
图2 标记的封装格式
3.1.1 VxWorks中MPLS协议的绑定
Vxworks提供了MUX层接口来分离数据链路层和网络层。网络层协议只需调用相应的MUX程序,就能得到数据链路层的设备提供的服务,同样,数据链路层的设备要想访问网络层协议(可以是IP或其他),它也只需调用相应的MUX程序。
通过MUX接口用户可以编写一个网络接口驱动程序或一个网络层协议,这样使得开发MPLS的系统可以独立于物理设备,使开发过程更简单。我们就是在MUX之上编写MPLS的功能模块的。由于MPLS介于第二层和第三层之间,应该在IP协议之前处理数据,因此我们绑定MPLS模块到MUX层上时,把它绑在IP层之前。在MPLS域入口节点LER的入接口我们将绑定类型设置为MUX_PROTO_SNARF,使其可以优先于IP截获分组,交给MPLS转发模块处理。在LER出接口和中间的LSR将绑定类型设置为0x8847(RFC3032所规定的以太网MPLS分组的链路帧类型)。在协议绑定时还要注册四个函数:mplsReceiveRtn、mplsShutdownRtn、mplsTxRestart、mplsError。MplsReceiveRtn函数为MPLS的接受函数,负责对接收到的MPLS分组进行拆包、标记交换及转发等。
3.1.1.2 MPLS分组的接收
由于Vxworks提供了接口用于向MUX发送数据,因此MPLS的发送函数比较简单。但是接受函数相对比较复杂。它首先要判断接受的函数是否是MPLS分组,如果是MPLS分组,就检查转发表里面是否存在转发表项,如果存在就进行标记交换,如果不存在,就表示分组到了MPLS域的出口,因此就须将数据交付给IP协议来处理;如果是IP分组,那么表示分组进入了MPLS域,那么首先看是否有这种类型的FEC(即按目的地址来查询转发表),如果存在发送数据,否则须向下游结点发送标记请求消息。
3.2 MPLS控制模块的实现
MPLS的控制模块由标记分发协议、标记信息库(LIB)、转发信息库(FIB)和流量管理信息库组成。由于流量管理信息库是可选部分,我们主要实现前三者。
3.2.1 标记分发协议的实现
3.2.1.1 LDP协议介绍
MPLS的有关标准中对标记分发协议定义了两种方式,一种是可以用控制信息携带,如利用BGP进行标签分发;第二种是采用专用的标记分发协议。而专用的标记分发协议又有两种:LDP/CR-LDP和RSVP,两种协议有着不同的消息集和信令处理规程。我们采用专用的标记分发协议LDP。
LDP是IETF的MPLS工作组制定的一个信令协议,用于创建和维护MPLS网络中节点的标记/FEC绑定。实际上LDP是一个LSR通知另一个LSR标记含义的过程。LDP协议允许两个LDP对等实体同时通过一个LDP会话获取对方的标记映射消息。RFC3036(LDP Specification)中定义的LDP消息有:Notification消息,Hello消息,Initialization消息,Keep Alive消息,Address消息,Address Withdraw消息,Label Mapping消息,Label Request消息,Label Abort Request消息,Label Withdraw消息,和Label Release消息。除Hello消息运行在UDP之上之外,其余都运行在TCP之上。
两个相互交换标记/FEC映射关系信息的LSR 互称为LDP对等节点, 它们之间通过LDP会话(LDP Session)交换信息。 存在LDP邻接(LDP Adjacency) 关系的 LDP对等节点之间可以知道相互的标记映射情况, 也就是说, 其间的协议是双向的。 FEC类别 将IP包精确地映射到各条LSP上是十分必要的, 因而需要给各条LSP提供一个FEC描述。 FEC定义了哪些IP包映射到哪条LSP上, 并使用唯一的标记值。 每个FEC由一个或多个FEC单元(FEC element)来描述。 每种FEC单元描述一组对应于特定LSP的IP包。 当某条LSP由多个FEC单元共享时, LSP应在共享状态发生改变的节点终止。
LDP协议标准允许选择不同的标记分发方式(下游自主标记分发/下游按需标记分发)、标记控制方式(有序标记控制/独立标记控制)和标记保持方式(保守标记保持方式/自由标记保持方式)。这些工作方式可任意组合,但一般来说,在标记空间资源有限的情况(如ATM-LSR)下推荐采用下游按需标记分发、保守标记保持方式,而下游自主标记分发一般和自由标记保持方式相对应。下面以下游按需标记分发为例说明LDP协议分发标记的过程。
图3 下游按需标记分发
如图3-3所示,首先标记交换路由器LERA、LSRB、LERC在各自端口用UDP发送hello消息,建立hello邻接。之后LERA和LSRB,LSRB和LERC之间分别建立TCP连接,建立LDP会话。分发标记时,沿LERA -> LSRB -> LERC的顺序发送标记请求,沿LERC -> LSRB -> LERA的顺序发送标记映射,从而建立起一条LSP(标记交换路径)。而在下游自主分发方式中,下游LSR无需收到上游LSR的标记请求就可以向上游发送标记映射。
下面给出了LDP协议初始化的状态转移图:
图4 LDP的初始化状态转移图
3.2.1.2 LDP协议的实现
LDP协议是基于TCP和UDP的,实现时采用Socket编程。这在技术上没有什么困难。但由于LDP协议本身十分庞大,实现起来工作量很大。而在Linux下已有LDP协议的实现。因此我们决定将Linux下的LDP模块移植到VxWorks下。实践证明我们的选择是明智的,由于Linux和VxWorks的TCP/IP协议栈均和BSD Socket兼容,移植工作比较顺利。移植过程中需要改动的主要是I/O接口部分和定时器部分,而在协议的核心——状态机部分基本上没有做什么改动。
3.2.1.2.1 LDP报文格式
大部分的LDP消息采用“类型-长度-值”(TLV, Type-Length-Value)的方案进行封装。下图给出了一个标记映射消息的例子:
图5 标记映射消息的封装格式
在实现过程中我们采用了Nortel公司提供的LDP编解码源文件,减小了工作量的同时也在一定程度上保证了协议实现与标准的一致性。
3.2.1.2.2 LDP状态机的实现
实现协议的状态机,关键技术是根据协议的状态转移图列出状态转移表(这在协议的状态机复杂的时候尤为必要)。有了状态转移表,编程实现就方便了。下面给出了实现图3-8中所示状态机的部分代码:
/* HELLO CONNECT INIT KEEP ADDR LABEL NOTIF ... */
/* NONE new ignore ignore ignore ignore ignore ignore ... */
/* NON_EXISTENT maint connect close close close close close ... */
/* INITIALIZED maint close recv_init close close close notif ... */
/* OPENSENT maint close recv_init close close close notif ... */
/* OPENREC maint close close finish close close notif ... */
/* OPERATIONAL maint close kmaint kmaint process process notif ... */
int ldp_state_table[LDP_STATE_NUM][LDP_EVENT_NUM] = {{0,6,6,6,6,6,6,6,6,6},
{1,3,7,7,7,7,7,6,7,6},
{1,7,2,7,7,7,9,7,7,6},
{1,7,2,7,7,7,9,7,7,6},
{1,7,7,4,7,7,9,7,7,7},
{1,7,8,8,5,5,9,7,7,7}};
ldp_return_enum (*ldp_state_func[LDP_FUNC_NUM])(ldp_global*,ldp_session*,
ldp_adj*,ldp_entity*,uint32_t,ldp_msg*,ldp_dest*) =
{
ldp_state_new_adjacency, /* 0 */
ldp_state_maintainance, /* 1 */
ldp_state_recv_init, /* 2 */
ldp_state_connect, /* 3 */
ldp_state_finish_init, /* 4 */
ldp_state_process, /* 5 */
ldp_state_ignore, /* 6 */
ldp_state_close, /* 7 */
ldp_state_keepalive_maintainance, /* 8 */
ldp_state_notification /* 9 */
};
3.2.1.2.3 LDP消息的处理
由于LDP协议消息种类较多,又分别有两种标记的分发、控制、保持方式,因此消息处理流程较为复杂。对于各种LDP消息的处理,RFC3036“LDP协议规范”的附录A中给出了详细的步骤,此处不再赘述,下面仅以标记请求消息为例,简要说明LDP消息的处理流程。
图6 收到标记请求消息后的处理流程
如图3-6所示,当LSR从上游LSR收到标记请求消息后,如果发现环路或发现FEC下一跳不存在,则向上游LSR发送通知消息,表示为什么不能提供FEC/标记绑定。否则若采用的是独立标记控制,则向上游LSR发送FEC/标记映射消息。若采用有序标记控制则向FEC下一跳发送标记请求消息。
3.2.1.2.4 LDP和其它模块的接口
目前的实现中提供了LDP和IP路由模块的接口函数:ldp_add_route()和ldp_del_route()。以及LDP和标记管理模块间的接口函数(在3.2.2中介绍)。
3.2.2 标记信息库(LIB)和转发信息库(FIB)的实现
LIB和FIB由LDP负责建立和维护。LIB由入标记信息库和出标记信息库组成。LDP的实现中分别为两者提供了接口函数ldp_mpls_inlabel_add ()、ldp_mpls_inlabel_del ()和ldp_mpls_outlabel_add ()、ldp_mpls_outlabel_del ()。以入标记信息库为例,其数据结构是一个二分树,其中每个接点的数据结构如下:
struct mpls_in_info
{
unsigned int __refcnt;
unsigned int mii_key;
unsigned int mii_age;
unsigned int mii_proto;
unsigned short mii_labelspace;
unsigned short mii_instruction_length;
struct mpls_label mii_label;
#ifdef CONFIG_ATM
struct atm_vcc *mii_vcc;
#endif
struct mpls_instruction mii_instruction[MPLS_NUM_OPS];
unsigned int mii_packets;
unsigned int mii_bytes;
unsigned int mii_drops;
};
转发信息库FIB由ILM(Incoming Label Map)表和FTN(FEC to NHLFE map)组成。ILM用来完成从入标记到出标记的映射,FTN用来完成从FEC到出标记的映射。LDP实现为ILM表和FTN表提供了接口函数mpls_fib_add_ilm()、mpls_fib_del_ilm()、mpls_fib_add_ftn()和mpls_fib_del_ftn(),同时FIB为MPLS转发模块提供了接口函数mpls_fib_get_ilm()和mpls_fib_get_ftn。ILM表和FTN表的数据结构均采用二分树,节点的数据结构如下:
struct mpls_nhlfe
{
struct mpls_label outlabel;
#define out_ifindex outlabel.ml_index
struct mpls_fec fec;
struct sockaddr next_hop;
unsigned short instruction_length;
struct mpls_instruction instruction[MPLS_NUM_OPS];
struct mpls_nhlfe_entry *next;
unsigned char exp; /* the exp bits in the label,probably for QoS use. */
};
struct mpls_ilm
{
struct mpls_label inlabel;
unsigned int label_space;
unsigned short protocol;
struct mpls_nhlfe nhlfe;
};
struct mpls_ftn
{
struct mpls_nhlfe nhlfe;
};
4. 实现过程中遇到的问题及解决方法。
在具体的实现过程中会遇到许多问题。比如在转发模块的实现中,MPLS域出口节点从MPLS分组中分离出IP报文后如何将其交给本机的IP层。一种可行的方法是分析IP包的内容,利用Raw Socket构造IP包后发送给自己。但这样做协议的层次关系不清晰,而且实现起来比较麻烦,运行效率也不高。在分析了VxWorks中WindNet协议栈的代码之后,我们找到了一个VxWorks中很少提到的函数。该函数能将完整的纯IP包交给本机的IP层处理,于是只用一个函数就解决了问题。又比如在移植Linux的LDP模块时有一些Linux的系统函数在VxWorks中没有对应的同名函数。这种情况下为了保证移植的正确性,首先应该弄明白这些系统函数的作用,然后在VxWorks中找到能实现相同功能的函数或者自己编写该函数。还有一些问题是始料不及的,例如LDP中的Hello消息采用UDP组播,我们在实现过程中发现组播报文能够发出却接收不到。调试了很久没有解决,最后将NE2000的网卡换成Intel的网卡居然就解决了问题,原来问题出在VxWorks下NE2000网卡的驱动程序上。
5. 结束语
本文论述了MPLS技术在VxWorks系统中的实现。本文中实现了MPLS的关键技术:MPLS的转发模块、标记分布协议和标记管理模块。下一步的工作中,我们将进一步对MPLS实现的互操作性和性能进行测试。同时我们将在此基础上研究实现CR-LDP(约束路由的LDP)和RSVP-TE,以实现QoS、流量工程和MPLS VPN。
参考文献
[1] RFC3031, Multiprotocol Label Switching Architecture, ftp://ftp.ietf.org/rfc/.
[2] RFC3032, MPLS Label Stack Encoding, ftp://ftp.ietf.org/rfc/
[3] RFC30, Use of Label Switching on Frame Relay Networks, ftp://ftp.ietf.org/rfc/.
[4] RFC3035, MPLS using LDP and ATM VC Switching, ftp://ftp.ietf.org/rfc/.
[5] RFC3036, LDP Specification, ftp://ftp.ietf.org/ rfc/.
[6] RFC3037, LDP Applicability, ftp://ftp.ietf.org/ rfc/.
[7] RFC3038, VCID Notification over ATM link for LDP, ftp://ftp.ietf.org/rfc/.
[8] RFC3063, MPLS Loop Prevention Mechanism, ftp://ftp.ietf.org/rfc/.
[9] RFC3212, Constraint-Based LSP Setup using LDP, ftp://ftp.ietf.org/rfc/.
[10] RFC3213, Applicability Statement for CR-LDP, ftp://ftp.ietf.org/rfc/.
[11] RFC3214, LSP Modification Using CR-LDP, ftp://ftp.ietf.org/rfc/.
[12] RFC3215, LDP State Machine, ftp://ftp.ietf.org/rfc/.
[13] 通信行业标准,编号YD/T 1162.1-2001 ,"多协议标记交换(MPLS)总体技术要求"。
[14] BruceDavice Yakov Rekhter,“MPLS:Technology and Applications”,中译本《多协议标签交换技术与应用》,罗志祥、朱志实、黄本雄、李非译,机械工业出版社。
[15] http://sourceforge.net/projects/mpls-linux/
[16] http://www.nortelnetworks.com/products/announcements/mpls/source/
[17] 孔祥营,柏桂枝. 嵌入式实时操作系统VxWorks. 中国电力出版社. 2001
[18] Tornado User's Guide (Windows Version) 1.0 Jan 96 ,Wind River System, Inc.
共7条
1/1 1 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |