IXP2400 NAT设计
作者:梁剑
Email:ixp2xxx@yahoo.com
2005-12-28
【摘要】
本文主要描述在Intel IXP2400 下的NAT 设计应用。包括NAT的Microblock 和Core Component、用户空间程序。Microblock 使用微码,CC和用户空间程序用标准C。本文中描述的NAT只实现MASQ。端口转换的策略简单,同时处理ARP没有考虑Cache,重复条目等。所以本设计的目的是了解如何使用基于IXA SDK架构设计Microblock 和CC ,以及之间的通讯协作。希望能起到抛砖引玉之功效。
【关键字】
IXP2400、Resource Manager(RM)、Core Component(CC)、Microblock、NAT、Linux Kernel、
Scratch Ring、TCP/IP
【正文】
Intel IXP2400 软件开发基本划分数据平面(Data plane)、控制平面(Control plane)、管理平面(Management plane)。数据平面分为慢路径(slow path)和快路径(fast path)。一般的设计是通过Mes(Microengines)完成fast path,Xscale完成slow path。理想的情况是大部分的包都通过Mes处理,Mes只处理拆封包、查询表、转发,这样才能尽可能的达到line rate。
本设计分Microblock 和Core Component、用户空间程序。重点在前两个部分,下面分别介绍。
A. Microblock:
NAT Microblock从packet_rx[] Microblock获得进入的包,处理NAT,如果在NAT_TABLE中没有找到对应的转换条目,则作为exception 包通过Scatch Ring 发送到CC处理。否则转发包到相应对传送队列中提供给sphy_mphy4_tx[] Microblock。
Micocode首先import_var 例如: NAT_TABLE_BASE、ARP_TABLE_BASE、TIMER_TABLE_BASE、GATEWAY_IPADDR。必要的LM(Local Memory)声明。信号、GPR、传输寄存器的声明和分配。$$pkt_hdr储存包的头部信息。$$iphdr储存IP包的头部信息。$rdata存放从RXtoNAT 的Scratch Ring获得的信息。
为context分配Local Memory资源(通过local_csr_wr[ACTIVE_LM_ADDR_0, LM_ADDR0_X]指令指定)以用做cache IP包的头部信息。
进入主循环:从RXtoNAT Scratch Ring 中取得信息放到$rdata,从$rdata中获得buffer handle和eop buffer handle、data offset、input port等信息。依靠buffer handle从DRAM中获得IP 包头部信息(40 bytes)Cache到$$iphdr寄存器中。判断是否需要作为exception 包发送到CC,之后判断是否是TCP/UDP/ICMP协议等。利用inport获得对应的IP地址和MAC地址,进而判断MAC是否是发送给本机器的,否则发送给CC。使用index寄存器把IP头部信息存储到Local Memory(注意位对齐问题)。之后从LM中获取5 tuples(IP src / IP dst/ protocol/ dst port / src port) ,根据 IP src ,IP dst,protocol,dst port,src port,out_interface执行NAT lookup查询,如果返回的nat port 为0,则lookup失败(NAT 表中没有对应的转换条目),作为exception 包发送CC去。否则做ARP lookup得到下一跳信息来修改包的头部信息。最后根据出去的端口选择合适的NATtoTX Scratch Ring(23:00 buffer handle,27:24 output port 31:28 reserved 31 valid bit)写入信息。对于本地包的处理这里不做说明。
B. CC:
过程如下:初始化RM,注册处理异常包的handle(这里设置接受模式为callback),使用RM API 分配buffer list,这里RX counter使用SRAM channel 0,Tx counter使用SRAM channel 1,NAT表、反转NAT表、ARP表放到DRAM,TIMER表放到SRAM。
Reset 所有的Mes,从UOF中获得microcode,patch microcode的symbols,创建Scratch rings,装载microcode到Mes中,初始化hash,开始Mes,最后为NAT 时间表创建一个执行引擎(先初始化cci,使用ix_cci_exe_run() 创建引擎)。
当一个exception包来的时候,RM 驱动检测到Mes的中断,则调用先前注册处理异常包的handle(nat_packet_handle)。Nat_packet_handle使用ix_rm_buffer_get_data()函数利用buffer_handle获得buf,使用ix_rm_buffer_get_meta得到meta_data(数据结构如图)