为什么X86防火墙小包性能不足的论述

来源:互联网 发布:gaga软件下载 编辑:程序博客网 时间:2024/04/28 01:51
 目前,很多X86的防火墙厂商都宣称,64bytes小包线速转发,94%……,呵呵,让我们来看看kola关于这个的经典论述<部份地方稍有修改>:

一. 线速

线速转发是对一个网络中转设备的理想要求。但平时大多数人都关注着设备的bps(bitsper second,每秒数据的位数),很少人会想到fps(frame per second,每秒数据的帧数)实际上更考验设备的转发能力。简单的说,bps是指每秒钟有多少字节的数据经过,fps是每秒钟有多少个数据包经过。以10Mb的网络来说,线速时bps为10M,fps最大值为14880。那么这个14880是怎么计算出来的呢?

首先我们要知道几个规定:

1. 以太网内最小的数据包的大小为64字节,它包括4字节的CRC,2字节的以太网类型(或长度),6字节的源Mac地址,6字节的目的Mac地址以及46字节的负荷.

2. 以太网帧与帧之间至少要有96位(12字节)的帧间隙(IFP,inter frame gap)以确保区分两个数据包。

3. 每个数据帧开始之间必须要有8字节的Mac地址前导位(MAC preamble)以确保发送方接收方同步数据位。

因此,以太网内最小的数据包实际上是64+12+8=84字节=672位。于是,10M网络环境下fps的最大值就是10M位每秒 / 672 位每帧 = 14480 帧每秒。同理,我们可以算出10M网络环境下fps的最大值为10M位每秒 / ( ( 1518+12+8 ) * 8 ) 位每帧 = 812 帧每秒,而100M网络环境下这两个值分别为148809和8127。

二. 处理能力

我们已经知道了线速情况下最大的fps值,现在我们看看要达到线速所需要的处理能力。假设市面上某防火墙的是X86架构的CII 900Mhz 的CPU,即每秒钟可以分成900M个时钟周期。于是,在100M的网络环境下,处理一个数据帧所允许的最大时钟周期为:900M 时钟周期每秒 / 148809 帧每秒 = 6048 时钟周期每帧也就是说,要达到线速转发,900Mhz的CPU平均要在6048个时钟周期内完成对一个数据包的处理。这只是理想情况,基于x86架构的系统里CPU还要负责各类中断(如系统时钟)的处理,次中断时都要保存当前的运行状态,切换到中断处理程序,等中断处理完后,再恢复当前状态,切换回原来的处理流程。光是这个切换过程至少都要费上500个时钟周期,还不包括中断处理程序所用的时钟周期。好在这类中断还”不算“频繁,扣除系统这部分开销后,真正分摊到每个数据包的处理时间平均大约还有5500个时钟周期。虽然Intel P3以上级的CPU如CII在设计指令集时已经将大量常用的指令(如两个寄存器相加/减)优化到可以在一个时钟周期内完成,但做为防火墙,更常用的是读/写内存数据(比如要比较源地址,计算IP的校验和等)这类多时钟周期的指令,所以5500个时钟周期内大约只能执行2000条指令。

对一个数据包的处理,从为这个数据包分配内存起,依次要检查以太网络协议(如果是RFC1042格式的数据包还要跳过LLC头找真正的以太网络协议),检查IP头、校验和(如果是TCP/UDP协议还要计算对应的校验和),DoS防御,状态检测,NAT规则,安全/统计规则,更新ARP/路由表,选择转发网卡,直到最终把这个数据包添加到发送队列中才算完成。你认为2000条x86的指令能完成这一切吗?

三. 现实数据

2000条指令看起来很多,实际上并不多,举个例子,要完成最简单的 A = A + B 这个算式最优化的指令也要用上两条:

mov eax, [val_B]

add [val_A], eax

未优化的会用上四条:

mov eax, [val_A]

mov ebx, [val_B]

add eax, ebx

mov [val_A], eax

目前的防火墙的开发大多是在Unix/Linux上完成的,以GCC编译器为例,它的优化效果比商业的编译器如VC/BC差了大概20%,也就是说同一段C代码,用商业编译器能编译成100条指令的话,GCC最好的情况下只能编译成120条指令。实际上,在没有任何包过滤规则或其它配置的情况下,完整的处理一个数据包需要大约14000条指令。

所以,根据上面的计算,目前许多X86架构防火墙(PIII 800)在100M网络环境下的结果是64byte的情况下达到42%的线速转发能力,即62000fps的处理能力。至于100%,95%,90%以上……

原创粉丝点击